PostgreSQL
 sql >> Datenbank >  >> RDS >> PostgreSQL

pqxx eine Arbeitstransaktion wiederverwenden/reaktivieren

pqxx::work ist nur eine pqxx::transaction<> die schließlich den größten Teil ihrer Logik von pqxx::transaction_base .

Diese Klasse soll nicht für mehrere Transaktionen dienen. Stattdessen ist es für eine einzelne Transaktion innerhalb eines Try/Catch-Blocks vorgesehen. Es hat eine Zustandsmitgliedsvariable (m_Status ), die niemals neu initialisiert wird, auch nicht nach einem Commit.

Das normale Muster ist:

{
    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;
    }
}

libpqxx könnte wohl die Transaktion beim Löschen rückgängig machen (um das try/catch vollständig zu vermeiden), aber das tut es nicht.

Es scheint, dass dies nicht zu Ihrem Nutzungsmuster passt, da Sie G_work möchten eine globale Variable sein, auf die von mehreren Stellen in Ihrem Programm aus zugegriffen werden kann. Bitte beachten Sie, dass pqxx::work nicht die Klasse für Verbindungsobjekte ist, sondern nur eine Möglichkeit, begin/commit/rollback mit der Behandlung von C++-Ausnahmen zu kapseln.

Nichtsdestotrotz erlaubt Ihnen libpqxx auch, Anweisungen außerhalb von Transaktionen (oder zumindest außerhalb von libpqxx-verwalteten Transaktionen) auszuführen. Sie sollten Instanzen von pqxx::nontransaction verwenden Klasse.

#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');");
}

Bitte beachten Sie, dass dies äquivalent ist zu:

#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');");
}

Letztendlich hindert Sie nichts daran, Transaktionen zu verwalten mit pqxx::nontransaction . Dies gilt insbesondere, wenn Sie Speicherpunkte möchten . Ich würde auch die Verwendung von pqxx::nontransaction empfehlen wenn Ihre Transaktion über einen Funktionsbereich hinaus dauern soll (z. B. im globalen Bereich).

#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;");
}