昨天處理項目中的一個業務需求要用到觸發器實現,觸發器中涉及到在inserting、deleting、updating之后來觸發對表的操作,對於inserting、updating中的操作都可以正常實現,就是deleting的時候,要求更新其他表,更新的值是對觸發器表自身的查詢操作,本人在有限的水平范圍之內試過N中方式來達到需求,最后無果,無奈之下只有找經理幫忙看看問題,最終問題被解決了,果然是用到了自己不太熟悉的oracle自治事務,而且這個自治事務因為是獨立的事務操作,考慮到事務回滾,必須單獨寫成一個觸發器來完成,最后問題被老大解決掉了,每次問題希望都是成長的機會,會有收獲,於是乎就到網上找了下自治事務(簡稱AT)相關方面的說明及用法,下午就到園子里來mark下,供自己學習及各位園友參考;
1、自治事務使用情況
無法回滾的審計 : 一般情況下利用觸發器禁止某些對表的更新等操作時,若記錄日志,則觸發器最后拋出異常時會造成日志回滾。利用自治事務可防止此點。
避免變異表: 即在觸發器中操作觸發此觸發器的表
在觸發器中使用ddl 寫數據庫:對數據庫有寫操作(insert、update、delete、create、alter、commit)的存儲過程或函數是無法簡單的用sql來調用的,此時可以將其設為自治事務,從而避免ora-14552(無法在一個查詢或dml中執行ddl、commit、rollback)、ora-14551(無法在一個查詢中執行dml操作)等錯誤。需要注意的是函數必須有返回值,但僅有in參數(不能有out或in/out參數)。
開發更模塊化的代碼: 在大型開發中,自治事務可以將代碼更加模塊化,失敗或成功時不會影響調用者的其它操作,代價是調用者失去了對此模塊的控制,並且模塊內部無法引用調用者未提交的數據。
2、Oracle 自制事務是指的存儲過程和函數可以自己處理內部事務不受外部事務的影響,用pragma autonomous_transaction來聲明,要創建一個自治事務,您必須在匿名塊的最高層或者存儲過程、函數、數據包或觸發的定義部分中,使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION語句。在這樣的模塊或過程中執行的SQL語句都是自治的。

create or replace procedure AutoNomouse_Insert is PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into Msg values('AutoNomouse Insert');
commit;
end;
3、自治事務可以嵌套,嵌套深度等只受init.ora參數transactions(同時並發的事務數,缺省為sessions的1.1倍)制約。因為自治事務是與主事務(簡稱MT)相分離的,所以它不能檢測到被修改過的行的當前狀態。這就好像在主事務提交之前,它們一直處於單獨的會話里,對自治事務來說,它們是不可用的。然而,反過來情況就不同了:主事務能夠檢測到已經執行過的自治事務的結果。
4、如果AT試圖訪問被MT控制的資源,可能有deadlock發生.Package 不能被聲明為AT,只有package所擁有的function和procedure 才能聲明為AT。主事務與自治事務是完全不同的事務,因此無法共享鎖等。結束一個自治事務必須提交一個commit、rollback或執行ddl,否則會產生Oracle錯誤ORA-06519: active autonomous transaction detected and rolled back 。保存點無法在自治事務中回滾到父事務中的一個保存點,只能在內部使用保存點。
5、可能遇到的錯誤
ora-06519 – 檢查到活動自治事務,回滾——退出自治事務時沒有提交、回滾或ddl操作
ora-14450 – 試圖訪問正在使用的事務級臨時表
ora-00060 – 等待資源時檢查到死鎖