我們知道數據庫的事務是一種單元操作要麼操作全部成功要麼操作全部失敗在Oracle數據庫中一個事務是從執行第一個數據管理語言(DML)語句開始直到執行一個COMMIT語句提交保存這個事務或者執行一個ROLLBACK語句放棄此次操作結束 事務的要麼全部完成要麼什麼都沒完成的特性會讓將錯誤信息記入數據庫表中變得很困難因為當事務失敗重新運行時用來編寫日志條目的INSERT語句還未完成 針對這種困境Oracle提供了一種便捷的方法即自治事務自治事務從當前事務開始在其自身的語境中執行它們能獨立地被提交或重新運行而不影響正在運行的事務正因為這樣它們成了編寫錯誤日志表格的理想形式在事務中檢測到錯誤時您可以在錯誤日志表格中插入一行並提交它然後在不丟失這次插入的情況下回滾主事務 因為自治事務是與主事務相分離的所以它不能檢測到被修改過的行的當前狀態這就好像在主事務提交之前它們一直處於單獨的會話裡對自治事務來說它們是不可用的然而反過來情況就不同了主事務能夠檢測到已經執行過的自治事務的結果 要創建一個自治事務您必須在匿名塊的最高層或者存儲過程函數數據包或觸發的定義部分中使用PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION語句在這樣的模塊或過程中執行的SQL Server語句都是自治的 觸發無法包含COMMIT語句除非有PRAGMA AUTONOMOUS_TRANSACTION標記但是只有觸發中的語句才能被提交主事務則不行 列表展示了對一個簡單但靈活的錯誤日志表格所作的CREATE TABLE和CREATE SEQUENCE語句
CREATE TABLE errorlog
( errorlog_id NUMBER
logged_on TIMESTAMP
DEFAULT SYSTIMESTAMP
logged_by VARCHAR() DEFAULT USER
num NUMBER num NUMBER
num NUMBER text VARCHAR()
text VARCHAR()
text VARCHAR() );
CREATE SEQUENCE errorlog_seq
START WITH INCREMENT BY ;
列表
是一個獨立的存儲過程
用於更新錯誤日志表格
CREATE OR REPLACEPROCEDURE log_error
( n IN NUMBER:=NULL t IN VARCHAR:=NULL
n IN NUMBER:=NULL t IN VARCHAR:=NULL
n IN NUMBER:=NULL t IN VARCHAR:=NULL )
IS PRAGMA AUTONOMOUS_TRANSACTION;BEGIN
INSERT INTO errorlog
(errorlog_id num num num text text text)
VALUES
(errorlog_seqNEXTVAL n n n t t t);
COMMIT;END;
這個過程接受最多三個數字和三個文本變量然後將它們和時間戳以及調用過程的用戶一起儲存在表格中 假如你要測試這個過程就需要更新(UPDATE)或刪除(DELETE)表格中的某些行這就引發了主事務然後執行存儲過程將您選擇的要記入日志的數據傳遞給它最後重新運行主事務選擇(SELECT)錯誤日志表格你的日志條目依舊會在原位置
From:http://tw.wingwit.com/Article/program/Oracle/201311/17944.html