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 は (try/catch を完全に回避するために) 削除時にトランザクションをロールバックできますが、そうではありません。
G_work
プログラムのいくつかの場所からアクセスできるグローバル変数にしたいので、これはあなたの使用パターンに合わないようです。pqxx::work は接続オブジェクトのクラスではなく、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;");
}