pqxx::work
est juste un pqxx::transaction<>
qui obtient finalement la majeure partie de sa logique de pqxx::transaction_base
.
Cette classe n'est pas destinée à servir pour plusieurs transactions. Au lieu de cela, il est destiné à une seule transaction dans un bloc try/catch. Il a une variable de membre d'état (m_Status
) qui n'est jamais réinitialisé, même après un commit.
Le modèle normal est :
{
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;
}
}
On peut dire que libpqxx pourrait annuler la transaction lors de la suppression (pour éviter complètement le try/catch), mais ce n'est pas le cas.
Il semble que cela ne corresponde pas à votre modèle d'utilisation comme vous le souhaitez G_work
être une variable globale accessible depuis plusieurs endroits de votre programme. Veuillez noter que pqxx::work n'est pas la classe des objets de connexion, mais juste un moyen d'encapsuler begin/commit/rollback avec la gestion des exceptions C++.
Néanmoins, libpqxx vous permet également d'exécuter des instructions en dehors des transactions (ou du moins en dehors des transactions gérées par libpqxx). Vous devez utiliser des instances de pqxx::nontransaction
classe.
#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');");
}
Veuillez noter que cela équivaut à :
#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');");
}
Finalement, rien ne vous empêche de gérer les transactions avec pqxx::nontransaction
. Cela est particulièrement vrai si vous voulez des des points de sauvegarde
. Je conseillerais également d'utiliser pqxx::nontransaction
si votre transaction est censée durer au-delà d'une portée de fonction (par exemple, à portée globale).
#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;");
}