pqxx::work
is just a pqxx::transaction<>
which eventually gets most of its logic from pqxx::transaction_base
.
This class is not intended to serve for several transactions. Instead, it is intended for a single transaction within a try/catch block. It has a state member variable (m_Status
) which is never reinitialized, even after a commit.
The normal pattern is:
{
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;
}
}
Arguably, libpqxx could rollback the transaction on deletion (to avoid the try/catch entirely) but it doesn't.
It seems that this doesn't fit your usage pattern as you want G_work
to be a global variable accessible from several places in your program. Please note that pqxx::work is not the class for connection objects, but just a way to encapsulate begin/commit/rollback with C++ exceptions handling.
Nevertheless, libpqxx also allows you to execute statement outside transactions (or at least outside libpqxx-managed transactions). You should use instances of pqxx::nontransaction
class.
#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');");
}
Please note that this is equivalent to:
#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');");
}
Eventually, nothing prevents you to manage transactions with pqxx::nontransaction
. This is especially true if you want savepoints. I would also advise using pqxx::nontransaction
if your transaction is meant to last beyond a function scope (e.g. at global scope).
#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;");
}