sql >> Databáze >  >> RDS >> PostgreSQL

pqxx znovu použít / znovu aktivovat pracovní transakci

pqxx::work je pouze pqxx::transaction<> který nakonec většinu své logiky získá z pqxx::transaction_base .

Tato třída není určena pro několik transakcí. Místo toho je určen pro jednu transakci v rámci bloku try/catch. Má členskou proměnnou stavu (m_Status ), který se nikdy znovu neinicializuje, ani po potvrzení.

Normální vzorec je:

{
    pqxx::work l_work(G_connexion);
    try {
        l_work.exec("insert into test.table1(nom) VALUES('foo');");
        l_work.commit();
    } catch (const exception& e) {
        l_work.abort();
        throw;
    }
}

Pravděpodobně by libpqxx mohl vrátit zpět transakci při smazání (aby se zcela vyhnul pokusu/úlovku), ale nedělá to.

Zdá se, že to neodpovídá vašemu vzorci použití, jak chcete G_work být globální proměnnou přístupnou z několika míst vašeho programu. Vezměte prosím na vědomí, že pqxx::work není třída pro objekty připojení, ale pouze způsob, jak zapouzdřit begin/commit/rollback se zpracováním výjimek C++.

Přesto vám libpqxx také umožňuje provádět příkazy mimo transakce (nebo alespoň mimo transakce spravované libpqxx). Měli byste použít instance pqxx::nontransaction třída.

#include "pqxx/nontransaction"

pqxx::connection G_connexion("dbname=basetest user=usertest password=1234");
pqxx::nontransaction G_work(G_connexion);

int f() {
    G_work.exec("insert into test.table1(nom) VALUES('foo');");
    G_work.exec("insert into test.table1(nom) VALUES('bar');");
}

Upozorňujeme, že toto je ekvivalentní:

#include "pqxx/nontransaction"

pqxx::connection G_connexion("dbname=basetest user=usertest password=1234");

int f() {
    pqxx::nontransaction l_work(G_connexion);
    l_work.exec("insert into test.table1(nom) VALUES('foo');");
    l_work.exec("insert into test.table1(nom) VALUES('bar');");
}

Nakonec vám nic nebrání ve správě transakcí s pqxx::nontransaction . To platí zejména, pokud chcete body uložení . Také bych doporučil použít pqxx::nontransaction pokud má vaše transakce trvat mimo rozsah funkcí (např. v globálním rozsahu).

#include "pqxx/nontransaction"

pqxx::connection G_connexion("dbname=basetest user=usertest password=1234");
pqxx::nontransaction G_work(G_connexion);

int f() {
    G_work.exec("begin;");
    G_work.exec("insert into test.table1(nom) VALUES('foo');");
    G_work.exec("savepoint f_savepoint;");
    // If the statement fails, rollback to checkpoint.
    try {
        G_work.exec("insert into test.table1(nom) VALUES('bar');");
    } catch (const pqxx::sql_error& e) {
        G_work.exec("rollback to savepoint f_savepoint;");
    }
    G_work.exec("commit;");
}



  1. Doctrine 2 QueryBuilder přidat více vybraných prvků/parametrů?

  2. [MySQL]:DELETE řádky ze dvou závislých tabulek

  3. Nejlepší způsob, jak uložit týdenní událost v MySQL?

  4. Začínáme s SQL Server 2017 na Linuxu na Azure Portal