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++例外処理でbegin/ commit/rollbackをカプセル化する方法にすぎないことに注意してください。
それでも、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;");
}