典型情境:存儲程序 Proc_SaveBill 儲存單據,呼叫函數 Func_GenerateCode 從序號表取得最大值並 +1 產生單號。若後續儲存失敗,序號已遞增導致「斷號」;若使用交易回滾,卻發現函數若含 COMMIT 則無法回滾,因交易只能回滾至上一個 COMMIT/ROLLBACK。
Oracle 提供 自主交易 機制,讓子程式在獨立交易區塊提交/回滾,不影響主交易。宣告方式:
CREATE OR REPLACE FUNCTION Func_GenerateCode RETURN VARCHAR2 IS
PRAGMA AUTONOMOUS_TRANSACTION; -- 宣告自主交易
v_code VARCHAR2(20);
BEGIN
-- 取得序號、更新序號表
UPDATE seq_table SET max_no = max_no + 1 WHERE id = 'BILL_NO'
RETURNING max_no INTO v_code;
COMMIT; -- 僅提交自主交易
RETURN 'BILL' || v_code;
END;
| 情境 | 一般函數/程序 | 自主交易 |
|---|---|---|
| 子程式含 COMMIT | 主交易無法回滾子程式變更 | 子程式獨立提交,主交易回滾不影響 |
| 子程式無 COMMIT | 主交易 ROLLBACK 可回滾子程式 | 仍需在子程式明確 COMMIT/ROLLBACK |
| 巢狀存儲程序呼叫 | 被呼叫者無錯誤則無法回滾 | 各自管理交易邊界 |
掌握自主交易是 PL/SQL 進階開發的關鍵技能,能優雅解決巢狀呼叫下的資料完整性難題。