pqxx::work
е просто pqxx::transaction<>
което в крайна сметка получава по-голямата част от логиката си от pqxx::transaction_base
.
Този клас не е предназначен да служи за няколко транзакции. Вместо това, той е предназначен за една транзакция в рамките на блок try/catch. Има членска променлива на състоянието (m_Status
), който никога не се инициализира отново, дори след ангажимент.
Нормалният модел е:
{
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 може да отмени транзакцията при изтриване (за да избегне напълно опита/улавянето), но не го прави.
Изглежда, че това не отговаря на вашия модел на използване, тъй като искате G_work
да бъде глобална променлива, достъпна от няколко места във вашата програма. Моля, обърнете внимание, че pqxx::work не е класът за обекти за връзка, а просто начин за капсулиране на start/commit/rollback с обработка на изключения в C++.
Независимо от това, libpqxx също така ви позволява да изпълнявате израз извън транзакции (или поне извън транзакции, управлявани от libpqxx). Трябва да използвате екземпляри на pqxx::nontransaction
клас.
#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');");
}
Моля, обърнете внимание, че това е еквивалентно на:
#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');");
}
В крайна сметка нищо не ви пречи да управлявате транзакции с pqxx::nontransaction
. Това е особено вярно, ако искате точки за запис
. Бих посъветвал също да използвате pqxx::nontransaction
ако вашата транзакция е предназначена да продължи извън обхват на функция (напр. в глобален обхват).
#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;");
}