在由 CALL
指令調用的程序以及匿名程式碼區塊(DO
指令)中,可以使用 COMMIT
和 ROLLBACK
指令來結束交易。在使用這些指令結束交易後,會自動啟動新的交易,因此沒有單獨的 START TRANSACTION
指令。(請注意,BEGIN
和 END
在 PL/pgSQL 中具有不同的含義。)
這是一個簡單的範例
CREATE PROCEDURE transaction_test1() LANGUAGE plpgsql AS $$ BEGIN FOR i IN 0..9 LOOP INSERT INTO test1 (a) VALUES (i); IF i % 2 = 0 THEN COMMIT; ELSE ROLLBACK; END IF; END LOOP; END; $$; CALL transaction_test1();
新的交易會以預設的交易特性(例如交易隔離等級)啟動。在迴圈中提交交易的情況下,可能需要使用與先前交易相同的特性自動啟動新的交易。COMMIT AND CHAIN
和 ROLLBACK AND CHAIN
指令可以實現此目的。
交易控制僅可能在頂層的 CALL
或 DO
調用中,或者在沒有任何其他介入指令的巢狀 CALL
或 DO
調用中。例如,如果調用堆疊是 CALL proc1()
→ CALL proc2()
→ CALL proc3()
,那麼第二個和第三個程序可以執行交易控制動作。但是,如果調用堆疊是 CALL proc1()
→ SELECT func2()
→ CALL proc3()
,則由於中間的 SELECT
,最後一個程序無法進行交易控制。
PL/pgSQL 不支援儲存點(SAVEPOINT
/ROLLBACK TO SAVEPOINT
/RELEASE SAVEPOINT
指令)。儲存點的典型使用模式可以用帶有例外處理器的區塊來替換(請參閱第 41.6.8 節)。在底層,帶有例外處理器的區塊會形成一個子交易,這意味著不能在這樣的區塊內結束交易。
特殊考慮適用於游標迴圈。考慮以下範例
CREATE PROCEDURE transaction_test2() LANGUAGE plpgsql AS $$ DECLARE r RECORD; BEGIN FOR r IN SELECT * FROM test2 ORDER BY x LOOP INSERT INTO test1 (a) VALUES (r.x); COMMIT; END LOOP; END; $$; CALL transaction_test2();
通常,游標會在交易提交時自動關閉。但是,像這樣在迴圈中建立的游標會在第一次 COMMIT
或 ROLLBACK
時自動轉換為可保持的游標。這意味著游標會在第一次 COMMIT
或 ROLLBACK
時被完全評估,而不是逐行評估。游標仍然會在迴圈後自動移除,因此這對於使用者來說幾乎是不可見的。但是必須記住,游標查詢所取得的任何表鎖定或行鎖定,在第一次 COMMIT
或 ROLLBACK
後將不再保持。
不允許在由非唯讀指令驅動的游標迴圈中使用交易指令(例如 UPDATE ... RETURNING
)。
如果您在文件中發現任何不正確、與您特定功能的使用經驗不符或需要進一步澄清的地方,請使用此表單來報告文件問題。