コードの一部を独自のトランザクションとしてコミットする必要がある状況があります。
テーブルを作成しましたsubtransaction_tbl
:
CREATE TABLE subtransaction_tbl
(
entryval integer
)
そして言語plpython3uの関数:
CREATE FUNCTION subtransaction_nested_test_t() RETURNS void
AS $$
plpy.execute("INSERT INTO subtransaction_tbl VALUES (1)")
with plpy.subtransaction():
plpy.execute("INSERT INTO subtransaction_tbl VALUES (2)")
$$ LANGUAGE plpython3u;
最初の状況:
BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select subtransaction_nested_test_t();
COMMIT TRANSACTION;
テーブルのエントリは正しいです:1,2,4
2番目の状況:
BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select subtransaction_nested_test_t();
ROLLBACK TRANSACTION;
テーブルの値が入力されていません
期待していた1
または2
をテーブルに追加する必要がありますsubtransaction_tbl
しかし、驚いたことに、値は挿入されませんでした。新しいサブトランザクションが関数によって開かれ、親トランザクションに依存するべきではないと想像しました。私が正しいかどうか知らせてください。
Postgresには自律的なトランザクションがありますか?または、plpython3u関数を変更する必要がありますか?
Postgres 11より前のPostgresにはno自律型トランザクションがあり、SQL procedures が追加されました。 関数で行われたすべてのことは、トランザクションでロールバックされます。
これは機能の議論です:
Postgres 10以前では、回避策は(ab-)use dblink を使用することです:
SAVEPOINT
の関連概念もあります。 (同じではありません!):
plpythonにはsubtransactions(with plpy.subtransaction():
)がありますが、自律型トランザクションとは異なります。別のCOMMIT
はありません。それがするすべては、それらをアトミックにするためにいくつかのステートメントを一緒にバンドルすることです。これがないと、途中で例外が発生し、その例外をキャッチすると、この例外までのコードのみが実行されます。それをサブトランザクションにラップする場合、それは全部かゼロかです。これは、自律型トランザクションではなく、SAVEPOINT
を使用するようなものです。 ドキュメントごと :
サブトランザクションコンテキストマネージャーはエラーをトラップしません。スコープ内で実行されたすべてのデータベース操作がアトミックにコミットまたはロールバックされることを保証するだけです。
Postgresはネストされたトランザクションをサポートしますが、それらは従来のSQLとは異なり、ネストされた部分的なポイントを持つトランザクションに似ています。
最上位には常に通常のBEGIN/COMMIT/ROLLBACK
があり、ネストされたレベルでは次のコマンドを使用する必要があります。
SAVEPOINT name
-トランザクションに固有の名前で新しいセーブポイントを作成しますRELEASE SAVEPOINT name
-セーブポイントをコミットしますが、含まれているトランザクションがコミットする場合にのみ持続しますROLLBACK TO SAVEPOINT name
-セーブポイントをロールバックしますまた、次のことも確認する必要があります。
SAVEPOINT
に使用される名前は一意です。SAVEPOINT
での失敗は、上位レベルに伝達されます。最後のビットは、自動的に実行できるライブラリを使用しない限り、少し注意が必要です。
pg-promise と書いたとき、これら2つの規定が保証されていることを確認しました。
level_1
、level_2
などのように自動的に生成されます。ROLLBACK TO SAVEPOINT name
に加えてトップレベルのROLLBACK
を実行します。すべて標準のpromise-chainingロジックに基づいて構築されています。説明されているPostgreSQLのネストされたトランザクションの limitations も参照してください...