PRAGMA AUTONOMOUS_TRANSACTION


轉自 http://blog.csdn.net/pan_tian/article/details/7675800

這段時間遇到一個問題,程序里明明插入了一條記錄,但在后邊的一段Procedure中卻查不到剛剛插入的記錄,最后發現這個Procedure的定義中加入了PRAGMA AUTONOMOUS_TRANSACTION。

PRAGMA AUTONOMOUS_TRANSACTION中文翻譯過來叫“自治事務”(翻譯的還算好理解),對於定義成自治事務的Procedure,實際上相當於一段獨立運行的程序段,這段程序不依賴於主程序,也不干涉主程序

自治事務的特點

第一,這段程序不依賴於原有Main程序,比如Main程序中有未提交的數據,那么在自治事務中是查找不到的。

第二,在自治事務中,commit或者rollback只會提交或回滾當前自治事務中的DML,不會影響到Main程序中的DML。

 

Autonomous Transaction Demo 1

Without Pragma Autonomous Transaction

 

  1. CREATE TABLE t (  
  2. test_value VARCHAR2(25));  
  3.   
  4. CREATE OR REPLACE PROCEDURE child_block IS  
  5.   
  6. BEGIN  
  7.   INSERT INTO t  
  8.   (test_value)  
  9.   VALUES  
  10.   ('Child block insert');  
  11.   COMMIT;  
  12. END child_block;  
  13. /  
  14.   
  15. CREATE OR REPLACE PROCEDURE parent_block IS  
  16.   
  17. BEGIN  
  18.   INSERT INTO t  
  19.   (test_value)  
  20.   VALUES  
  21.   ('Parent block insert');  
  22.   
  23.    child_block;  
  24.   
  25.    ROLLBACK;  
  26. END parent_block;  
  27. /  
  28.   
  29. -- run the parent procedure  
  30. exec parent_block  
  31.   
  32. -- check the results  
  33. SELECT * FROM t;  

 

 

  1. Output:  
  2. Parent block insert  
  3. Child block insert  

With Pragma Autonomous Transaction

  1. CREATE OR REPLACE PROCEDURE child_block IS  
  2.   
  3. PRAGMA AUTONOMOUS_TRANSACTION;  
  4.   
  5. BEGIN  
  6.   INSERT INTO t  
  7.   (test_value)  
  8.   VALUES  
  9.   ('Child block insert');  
  10.   
  11.   COMMIT;  
  12. END child_block;  
  13. /  
  14.   
  15. CREATE OR REPLACE PROCEDURE parent_block IS  
  16.   
  17. BEGIN  
  18.   INSERT INTO t  
  19.   (test_value)  
  20.   VALUES  
  21.   ('Parent block insert');  
  22.   
  23.    child_block;  
  24.   
  25.    ROLLBACK;  
  26. END parent_block;  
  27. /  
  28. -- empty the test table  
  29. TRUNCATE TABLE t;  
  30.   
  31. -- run the parent procedure  
  32. exec parent_block;  
  33.   
  34. -- check the results  
  35. SELECT * FROM t;  
  1. Output:  
  2. Child block insert  

 

 

Autonomous Transaction Demo 2

Without Pragma Autonomous Transaction

 

 

  1. DROP TABLE t;  
  2.   
  3. CREATE TABLE t (testcol NUMBER);  
  4.   
  5. CREATE OR REPLACE FUNCTION howmanyrows RETURN INTEGER IS  
  6.  i INTEGER;  
  7. BEGIN  
  8.   SELECT COUNT(*)  
  9.   INTO i  
  10.   FROM t;  
  11.   
  12.   RETURN i;  
  13. END howmanyrows;  
  14. /  
  15.   
  16. CREATE OR REPLACE PROCEDURE testproc IS  
  17.  a INTEGER;  
  18.  b INTEGER;  
  19.  c INTEGER;  
  20. BEGIN  
  21.   SELECT COUNT(*)  
  22.   INTO a  
  23.   FROM t;  
  24.   
  25.   INSERT INTO t VALUES (1);  
  26.   COMMIT;  
  27.   
  28.   INSERT INTO t VALUES (2);  
  29.   INSERT INTO t VALUES (3);  
  30.   
  31.   b := howmanyrows;  
  32.   
  33.   INSERT INTO t VALUES (4);  
  34.   INSERT INTO t VALUES (5);  
  35.   INSERT INTO t VALUES (6);  
  36.   COMMIT;  
  37.   
  38.   SELECT COUNT(*)  
  39.   INTO c  
  40.   FROM t;  
  41.   
  42.   dbms_output.put_line(a);  
  43.   dbms_output.put_line(b);  
  44.   dbms_output.put_line(c);  
  45. END testproc;  
  46. /  
  47.   
  48. set serveroutput on  
  49.   
  50. exec testproc  
  1. Output:  
  2. 0  
  3. 3  
  4. 6  
  5. Total execution time 2.782 sec.  

With Pragma Autonomous Transaction

 

 

  1. CREATE OR REPLACE FUNCTION howmanyrows RETURN INTEGER IS  
  2.  i INTEGER;  
  3.   
  4.  PRAGMA AUTONOMOUS_TRANSACTION;  
  5. BEGIN  
  6.   SELECT COUNT(*)  
  7.   INTO i  
  8.   FROM t;  
  9.   
  10.   RETURN i;  
  11. END howmanyrows;  
  12. /  
  13.   
  14. -- empty the test table  
  15. TRUNCATE TABLE t;  
  16.   
  17. exec testproc;  
    1. Output:  
    2. 0  
    3. 1  
    4. 6  

在觸發器中操作觸發此觸發器的表,用PRAGMA AUTONOMOUS_TRANSACTION選項。

15.1為何使用自治事務 無法回滾的審計

一般情況下利用觸發器禁止某些對表的更新等操作時,若記錄日志,則觸發器最后拋出異常時會造成日志回滾。利用自治事務可防止此點。

避免變異表

即在觸發器中操作觸發此觸發器的表

在觸發器中使用DDL 寫數據庫

對數據庫有寫操作(INSERT、UPDATE、DELETE、CREATE、ALTER、COMMIT)的存儲過程或函數是無法簡單的用SQL來調用的,此時可以將其設為自治事務,從而避免ORA-14552(無法在一個查詢或DML中執行DDL、COMMIT、ROLLBACK)、ORA-14551(無法在一個查詢中執行DML操作)等錯誤。需要注意的是函數必須有返回值,但僅有IN參數(不能有OUT或IN/OUT參數)。

開發更模塊化的代碼

在大型開發中,自治事務可以將代碼更加模塊化,失敗或成功時不會影響調用者的其它操作,代價是調用者失去了對此模塊的控制,並且模塊內部無法引用調用者未提交的數據。

15.2 如何工作 事務控制

DECLARE整個塊都是屬於父事務的,自治事務從離PRAGMA后的第一個BEGIN開始,只要此BEGIN塊仍在作用域,則都屬於自治事務。例如在DECLARE模塊中聲明一個寫數據庫的函數,則此函數雖然在自治事務所在存儲過程執行,但其屬於父事務;而自治事務中調用的任何函數和存儲過程、激發的任何觸發器等均為此自治事務的一部分。

自治事務可以嵌套,嵌套深度等只受INIT.ORA參數TRANSACTIONS(同時並發的事務數,缺省為SESSIONS的1.1倍)制約。

作用域

1. 包中的變量

自治事務可看到並修改父事務的變量,父事務也會察覺到這一改變,且不存在回滾問題。

2. 會話設置/參數

自治事務與父事務共享同一個會話環境,通過ALTER SESSION作的修改對整個會話均有效。但SET TRANSACTION是事務級的,僅對提起修改的事務有效。

3. 數據庫修改

父事務已提交的修改對自治事務可見,未提交的對自治事務不可見,自治事務的修改對父事務是否可見取決於隔離級別(Isolation Level)。

對於游標,取決於其打開的位置,若其在父事務中打開,則之前父事務未提交的修改對其是有效的,在自治事務中這些修改也可見;而在自治事務中打開,則父事務未提交的修改不可見。

若使用缺省的READ COMMITTED隔離級別,則自治事務的修改對父事務可見;若改用SERIALIZABLE,則不可見。

4. 鎖

父事務與自治事務是完全不同的事務,因此無法共享鎖等。

結束一個自治事務必須提交一個COMMIT、ROLLBACK或執行DDL。

保存點無法在自治事務中回滾到父事務中的一個保存點,只能在內部使用保存點。

15.3 最后說明 不支持分布式事務截至8.1.7在自治事務中不支持分布式事務

僅可用PL/SQL 全部事務回滾若自治事務出錯,則全部回滾,即便父事務有異常處理模塊。

事務級臨時表每個會話僅一個事務可訪問事務級臨時表(多個會話中的事務可並發操作)。

15.4 可能遇到的錯誤
ORA-06519 – 檢查到活動自治事務,回滾——退出自治事務時沒有提交、回滾或DDL操作

ORA-14450 – 試圖訪問正在使用的事務級臨時表

ORA-00060 – 等待資源時檢查到死鎖

 

 


在create prodedure 時可以指定PRAGMA AUTONOMOUS_TRANSACTION;

當前的存儲過程作為已有事務的子事務運行,子事務的commit,rollback操作不影響父事務的狀態

有的時候,希望在select語句中使用自己定義的函數,並且這個函數除了返回特定的值之外,還執行update,insert,delete等操作。

對數據庫有寫操作(update,insert,delete,crate,alert,commit)的函數是無法簡單的用SQL來調用的。

ORA-14551: cannot perform. a DML operation inside a query

如何實現?關鍵是pragma autonomous_transaction

如下例子:

   Create or replace function func_getid return int is
  2 pragma autonomous_transaction;
  3 vid int;
  4 begin
  5 select max(id) into vid from test_id;
  6 update test_id set id=id+1;
  7 commit;
  8 return vid;
  9 end;
  10 /
  Function created
   select func_getid from dual;
  FUNC_GETID
  ----------
  1
   select func_getid from dual;
  FUNC_GETID
  ----------
  2

PRAGMA AUTONOMOUS_TRANSACTION 自治事物

DROP TABLE test_1;

CREATE TABLE test_1 (ID NUMBER PRIMARY KEY , NAME VARCHAR2(20));


CREATE OR REPLACE PROCEDURE test_proce IS
2 PRAGMA AUTONOMOUS_TRANSACTION; -------------自治事物的標示
3 BEGIN
4 INSERT INTO test_1 VALUES(2,'peter');
5 COMMIT;
6 END;
7 /



BEGIN
2 INSERT INTO test_1 VALUES(1,'joe');
3 test_proce; -----------------只COMMIT了自己沒有全局COMMIT
4 ROLLBACK; -----------------只有回滾了joe
5 END;
6 /

SELECT * FROM test_1;

ID NAME
---------- --------------------
2 peter

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM