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