pqxx::work
to tylko pqxx::transaction<>
który ostatecznie uzyskuje większość swojej logiki z pqxx::transaction_base
.
Ta klasa nie jest przeznaczona do obsługi kilku transakcji. Zamiast tego jest przeznaczony do pojedynczej transakcji w bloku try/catch. Ma zmienną składową stanu (m_Status
), który nigdy nie jest ponownie inicjowany, nawet po zatwierdzeniu.
Normalny wzór to:
{
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;
}
}
Prawdopodobnie libpqxx może cofnąć transakcję po usunięciu (aby całkowicie uniknąć próby/złapania), ale tak się nie dzieje.
Wygląda na to, że nie pasuje to do twojego wzorca użytkowania, jak chcesz G_work
być zmienną globalną dostępną z kilku miejsc w twoim programie. Proszę zauważyć, że pqxx::work nie jest klasą dla obiektów połączeń, a jedynie sposobem na enkapsulację begin/commit/rollback z obsługą wyjątków C++.
Niemniej jednak libpqxx pozwala również na wykonywanie instrukcji poza transakcjami (lub przynajmniej poza transakcjami zarządzanymi przez libpqxx). Powinieneś użyć instancji pqxx::nontransaction
klasa.
#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');");
}
Pamiętaj, że jest to równoznaczne z:
#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');");
}
Ostatecznie nic nie stoi na przeszkodzie w zarządzaniu transakcjami z pqxx::nontransaction
. Jest to szczególnie ważne, jeśli chcesz punkty zapisu
. Radziłbym również użyć pqxx::nontransaction
jeśli Twoja transakcja ma trwać poza zakresem funkcji (np. w zakresie globalnym).
#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;");
}