DBMS_TRANSACTION是一個相容Oracle文法的內建包,用於在PL/SQL程式塊(如預存程序、函數)中實現對事務的精細化控制。當您需要在一段複雜的商務邏輯中撤銷部分操作而非復原整個事務時,可以使用該包提供的儲存點(Savepoint)功能,實現更靈活的交易管理。
功能簡介
PolarDB PostgreSQL版(相容Oracle)支援以下四個函數:
SAVEPOINT:標記事務中的儲存點,用於復原到指定儲存點。ROLLBACK_SAVEPOINT:復原到指定儲存點,用於撤銷儲存點後的操作。COMMIT:提交當前事務,用於永久化更改資料。ROLLBACK:復原整個事務,用於撤銷所有未提交的操作。
前提條件
僅支援Oracle文法相容 2.0,且核心小版本需為2.0.14.17.34.0及以上版本。
注意事項
使用
SAVEPOINT和ROLLBACK_SAVEPOINT前,請先開啟polar_default_pl_stmt_transaction_rollback參數。COMMIT或ROLLBACK會結束當前事務,如需繼續使用,需重新開始新事務。頻繁使用
SAVEPOINT可能會增加事務開銷,建議合理規劃事務的粒度。不支援
BEGIN_WORK及SET_TRANSACTION等進階功能。EXECUTE IMMEDIATE情境中,若需使用COMMIT/ROLLBACK,請先開啟polar_enable_commit_in_execute_immediate參數。
SAVEPOINT
在事務中設定儲存點(Savepoint),用於後續復原到該點。
文法
DBMS_TRANSACTION.SAVEPOINT(savepoint_name VARCHAR2);參數說明
參數 | 描述 |
| 儲存點的名稱。 |
樣本
DECLARE
BEGIN
-- 插入測試資料
INSERT INTO test_table (id, name) VALUES (1, 'Alice');
-- 設定儲存點
DBMS_TRANSACTION.SAVEPOINT('sp1');
-- 執行可能失敗的操作
INSERT INTO test_table (id, name) VALUES (2, 'Bob');
-- 提交事務
COMMIT;
END;事務開始後,插入一條資料,並記錄儲存點sp1。
若後續操作失敗,可通過
ROLLBACK_SAVEPOINT復原到sp1。最後
COMMIT提交事務,所有更改生效。
ROLLBACK_SAVEPOINT
復原事務到指定儲存點(Savepoint),撤銷儲存點之後的操作。
文法
DBMS_TRANSACTION.ROLLBACK_SAVEPOINT(savepoint_name VARCHAR2);參數說明
參數 | 描述 |
savepoint_name | 儲存點的名稱。 |
樣本
DECLARE
BEGIN
-- 插入第一條記錄
INSERT INTO test_table (id, name) VALUES (1, 'Alice');
-- 設定儲存點
DBMS_TRANSACTION.SAVEPOINT('sp1');
-- 插入第二條記錄(可能失敗)
INSERT INTO test_table (id, name) VALUES (2, 'Bob');
-- 復原到儲存點 sp1
DBMS_TRANSACTION.ROLLBACK_SAVEPOINT('sp1');
-- 提交事務
COMMIT;
END;事務開始後,插入一條資料Alice,並記錄儲存點sp1。
插入第二條資料,並通過
ROLLBACK_SAVEPOINT('sp1')復原,Bob的記錄不會被保留。最後
COMMIT提交事務,僅保留了Alice的插入資料。
COMMIT
提交當前事務,使所有更改永久生效。
文法
DBMS_TRANSACTION.COMMIT();樣本
DECLARE
BEGIN
-- 插入兩條記錄
INSERT INTO test_table (id, name) VALUES (1, 'Alice');
INSERT INTO test_table (id, name) VALUES (2, 'Bob');
-- 提交事務
DBMS_TRANSACTION.COMMIT();
END;事務開始後,插入兩條資料。
調用COMMIT提交事務。所有更改將被永久寫入資料庫。
若未顯式提交,事務在程式塊結束時自動認可(取決於資料庫配置)。
ROLLBACK
復原整個事務,撤銷所有未認可的變更。
文法
DBMS_TRANSACTION.ROLLBACK();樣本
DECLARE
BEGIN
-- 插入第一條記錄
INSERT INTO test_table (id, name) VALUES (1, 'Alice');
-- 類比錯誤
IF 1 = 1 THEN
RAISE_APPLICATION_ERROR(-20001, '人為觸發錯誤');
END IF;
-- 提交事務(不會執行)
DBMS_TRANSACTION.COMMIT();
EXCEPTION
WHEN OTHERS THEN
-- 復原整個事務
DBMS_TRANSACTION.ROLLBACK();
DBMS_OUTPUT.PUT_LINE('事務已復原');
END;事務開始後,插入一條資料Alice後,觸發人為錯誤。
在異常處理
EXCEPTION中調用ROLLBACK(),撤銷所有未認可的變更。最後事務被復原,test_table中無新增記錄。