pqxx::work
ist nur eine pqxx::transaction<>
, die schließlich die meisten ihrer Logik von pqxx::transaction_base
bekommt.
Diese Klasse ist nicht für mehrere Transaktionen vorgesehen. Stattdessen ist es für eine einzelne Transaktion innerhalb eines try/catch-Blocks vorgesehen. Es hat eine Statuselementvariable (m_Status
), die selbst nach einem Commit nie neu initialisiert wird.
Das normale Muster:
{
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;
}
}
Argumentieren, libpqxx die Transaktion beim Löschen Rollback könnte (die versuchen zu vermeiden/fangen ganz), aber es funktioniert nicht.
Es scheint, dass dies nicht Ihrem Verwendungsmuster entspricht, da Sie G_work
eine globale Variable sein möchten, die von mehreren Stellen in Ihrem Programm zugänglich ist. Bitte beachten Sie, dass pqxx :: work nicht die Klasse für Verbindungsobjekte ist, sondern nur eine Möglichkeit, um begin/commit/rollback mit C++ - Ausnahmen zu kapseln.
Dennoch ermöglicht es libpqxx auch, Anweisungen außerhalb von Transaktionen auszuführen (oder zumindest außerhalb von von libpqxx verwalteten Transaktionen). Sie sollten Instanzen der Klasse pqxx::nontransaction
verwenden.
#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 entspricht:
#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');");
}
Schließlich nichts hindert Sie Transaktionen mit pqxx::nontransaction
zu verwalten. Dies gilt insbesondere, wenn Sie savepoints möchten. Ich würde auch empfehlen, pqxx::nontransaction
zu verwenden, wenn Ihre Transaktion über einen Funktionsumfang hinaus dauern soll (z. B. im globalen Gültigkeitsbereich).
#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;");
}
Haben Sie gefunden, eine Antwort? – Michael
Nein. Da niemand eine Antwort zu haben scheint, füge ich jeder Klasse in meiner Software eine Datenbankklasse hinzu und gebe sie bei Bedarf durch Methoden weiter. Eine eindeutige globale Transaktion war zu gefährlich, da ich sie nicht erneut aktivieren konnte, wenn sie fehlschlug. – alexis