本文介紹了交易管理的相關內容。
簡介
在由CALL命令調用的過程中以及匿名代碼塊(DO命令)中,可以用命令COMMIT和ROLLBACK結束事務。在一個事務被使用這些命令結束後,一個新的事務會被自動開始,因此沒有單獨的START TRANSACTION命令(注意BEGIN和END在 PL/SQL 中有不同的含義)。
這裡是一個簡單的例子:
CREATE PROCEDURE transaction_test1()
IS
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。
對於遊標迴圈有特殊的考慮。看看這個例子:
CREATE PROCEDURE transaction_test2()
IS
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處會被完全計算出來,而不是逐行被計算。該遊標在迴圈後仍會被自動刪除,因此這通常對使用者是不可見的。
有非唯讀命令(UPDATE ... RETURNING)驅動的遊標迴圈中不允許有事務命令。
事務在一個具有異常處理部分的塊中不能被結束。