回答:
必要なのは、いわゆる「自律型トランザクション」(Oracleが提供する機能)です。現時点では、これはまだPostgreSQLでは不可能です。ただし、SAVEPOINTを使用できます。
BEGIN;
INSERT ...
SAVEPOINT a;
some error;
ROLLBACK TO SAVEPOINT a;
COMMIT;
完全に独立したトランザクションではありませんが、「すべてのトランザクション」を正しく取得できます。これを使用して、自律型トランザクションに期待することを実現できます。
そうでなければ、この時点で他の合理的な解決策はありません。
あなたはそれを自分で試すことができます:
警告:進行中のトランザクションが既にあります
ネストされたトランザクションはPostgreSQLに実装されていないため、新しい(サブ)トランザクションは開始されません。(pl/pgsql
ただし、たとえば、その振る舞いを模倣するような関数で魔法をかけることができます。)
PostgreSQL 11を使用すると、新しい実際のストアドプロシージャとトランザクション処理能力により、ネストされたトランザクションが可能になると考えることができます。ただし、ドキュメントによると、そうではありません。
CALL
コマンドおよび匿名コードブロック(DO
command)で呼び出されるプロシージャでは、コマンドCOMMIT
とを使用してトランザクションを終了することができますROLLBACK
。これらのコマンドを使用してトランザクションが終了すると、新しいトランザクションが自動的に開始されるため、個別のSTART TRANSACTIONコマンドはありません。
PostgreSQLはサブトランザクションをサポートしていませんが、このSAVEPOINT
機能はニーズに効果的に応えることができます。GitHubのVitaly Tomilovによる約束を介した、PGへのAdvanced access layerのドキュメントからの引用:
PostgreSQLは、ネストされたトランザクションを適切にサポートしていません。トランザクション内のセーブポイントを介した部分的なロールバックのみをサポートしています。さらに説明したように、2つの手法の違いは非常に大きくなります。
ネストされたトランザクションの適切なサポートは、親トランザクションがロールバックされたときに、成功したサブトランザクションの結果がロールバックされないことを意味します。ただし、PostgreSQLのセーブポイントでは、トップレベルのトランザクションをロールバックすると、すべての内部セーブポイントの結果もロールバックされます。
セーブポイントは、アクティブなトランザクション内の以前のポイントへの部分的なロールバックに使用できます。たとえば、セーブポイントを確立し、確立後に実行されたすべてのコマンドの効果を後で元に戻すには、次のようにします。
BEGIN;
INSERT INTO table1 VALUES (1);
SAVEPOINT my_savepoint;
INSERT INTO table1 VALUES (2);
ROLLBACK TO SAVEPOINT my_savepoint;
INSERT INTO table1 VALUES (3);
COMMIT;
上記のトランザクションは、値1と3を挿入しますが、2は挿入しません。詳細については、SAVEPOINT
ドキュメントを参照してください。
Postgresql 9.5以降では、pg_background拡張機能によって提供される動的なバックグラウンドワーカーを使用できます。自律型トランザクションを作成します。拡張機能のgithubページを参照してください。溶解はdb_linkよりも優れています。PostgreSQLの自律トランザクションサポートに関する完全なガイドがあります。