簡體   English   中英

Postgres是否支持嵌套或自治事務?

[英]Does Postgres support nested or autonomous transactions?

我有一種情況,我必須提交一部分代碼作為自己的事務。
我創建了一個表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

第二種情況:

BEGIN TRANSACTION;
INSERT INTO subtransaction_tbl VALUES (4);
select  subtransaction_nested_test_t();
ROLLBACK TRANSACTION;

表中的值未填充

我預計應該將12添加到表subtransaction_tbl但令我驚訝的是沒有插入任何值。 我想象一個新的子事務由函數打開,它不應該依賴於父事務。 如果我是對的,請告訴我。

Postgres有自動交易嗎? 或者我是否必須修改我的plpython3u函數?

Postgres確實支持嵌套事務,但它們與傳統SQL不同,更像是具有嵌套部分點的事務。

在頂層,您始終具有典型的BEGIN/COMMIT/ROLLBACK ,並且在嵌套級別上,您必須使用以下命令:

  • SAVEPOINT name - 創建一個新的保存點,其名稱對事務而言是唯一的
  • RELEASE SAVEPOINT name - 提交保存點,但只有在包含事務提交時才會保留
  • ROLLBACK TO SAVEPOINT name - 回滾保存點

您還必須確保:

  • 每個SAVEPOINT使用的名稱都是唯一的;
  • 一個SAVEPOINT失敗向上傳播到頂層。

最后一點有點棘手,除非您使用可以自動為您執行此操作的庫。

當我寫pg-promise時 ,我確保這兩項規定得到保證:

  • 它根據事務級別自動生成保存點名稱,如level_1level_2等;
  • 它執行包含ROLLBACK TO SAVEPOINT name ,以及子事務失敗時的頂級ROLLBACK - 所有這些都構建在標准的promise-chaining邏輯上。

另請參閱解釋的PostgreSQL嵌套事務的局限性 ......

Postgres 11之前沒有自動交易,其中添加了SQL 程序 函數中完成的所有操作都將與事務一起回滾。

以下是對該功能的討論:

在Postgres 10或更早版本中,解決方法可能是(ab-)使用dblink

還有SAVEPOINT的相關概念。 (不一樣!):

plpython

with plpy.subtransaction():子事務with plpy.subtransaction(): ,但這與自治事務不同。 沒有單獨的COMMIT 它所做的只是將幾個語句捆綁在一起,使它們成為原子。 如果沒有它,如果異常發生在中間某處,並且您捕獲該異常,則只會執行此異常的代碼。 如果將它包裝成子事務,則全部或全部。 這就像使用SAVEPOINT ,而不是自治事務。 每個文件

子事務上下文管理器不會捕獲錯誤,它只確保在其作用域內執行的所有數據庫操作都將以原子方式提交或回滾。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM