sql >> データベース >  >> RDS >> PostgreSQL

pqxx再利用/作業トランザクションの再アクティブ化

    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;");
    }
    



    1. OraOLEDB.Oracleプロバイダーがローカルマシンに登録されていません

    2. CakePHP3-関連付けに依存している場合に関連付けを使用してデータを保存する

    3. Postgresで左外部結合を使用して削除する

    4. 2020年の計画でデータベース監視を優先する必要がある4つの理由