Oracle-11g
Oracle 中的回滾
我在 Oracle 回滾中遇到問題。
在我的儲存過程中,我有多個插入和更新語句。如果一切正常,我將發送成功消息,並將成功狀態跟踪到一個 Z_AUDIT_HISTORY 表中。
現在我在失敗狀態中需要的同樣的東西也首先需要回滾所有語句,然後將失敗狀態跟踪到這個 Z_AUDIT_HISTORY 表中。
我的程序:
create or replace PROCEDURE SPTest AS BEGIN SAVEPOINT sp_sptest; insert into emptest(empid,empname,deptno) (1,'ravi',10); insert into test1(id,name,sal) (1,'raju',4444); update emptest set empname='hari' where empid=1; INSERT INTO Z_AUDIT_HISTORY(AUDIT_HISTORTY_ID,STATUS) VALUES(SEQ_AUDIT_HISTORTY_ID.NEXTVAL,'SUCESS'); DBMS_OUTPUT.PUT_LINE('Sucess'); EXCEPTION WHEN OTHERS THEN INSERT INTO Z_AUDIT_HISTORY(AUDIT_HISTORTY_ID,ASSET_ID,STATUS) VALUES(SEQ_AUDIT_HISTORTY_ID.NEXTVAL,p_asset_id,'FAIL'); DBMS_OUTPUT.PUT_LINE('Whoops'); ROLLBACK TO sp_sptest; RAISE; END;
當我執行我的程序時,我遇到了錯誤。
ORA-06512: at line 1 01438. 00000 - "value larger than specified precision allowed for this column" *Cause: When inserting or updating records, a numeric value was entered that exceeded the precision defined for the column. *Action: Enter a value that complies with the numeric column's precision, or use the MODIFY option with the ALTER TABLE command to expand the precision.
這裡發生了三件事。
- 處理異常時,您先執行插入操作,然後執行回滾操作。這意味著插入也被回滾。至少,切換語句的順序:
DBMS_OUTPUT.PUT_LINE('Whoops'); ROLLBACK TO sp_sptest; INSERT INTO Z_AUDIT_HISTORY(AUDIT_HISTORTY_ID,ASSET_ID,STATUS) VALUES(SEQ_AUDIT_HISTORTY_ID.NEXTVAL,p_asset_id,'FAIL'); RAISE;
- 更好的是,處理自治事務中的日誌記錄。這意味著它是一個獨立的事務,不受主事務中發生的任何事情的影響。對於日誌記錄,您需要這個。
CREATE OR REPLACE PROCEDURE log_audit( p_asset_id NUMBER, p_status VARCHAR ) AS PRAGMA AUTONOMOUS TRANSACTION BEGIN INSERT INTO z_audit_history(audit_history_id, asset_id, status) VALUES(seq_audit_history_id.NEXTVAL, p_asset_id, p_status); END;
並稱它為
DBMS_OUTPUT.PUT_LINE('Whoops'); ROLLBACK TO sp_sptest; log_audit(p_asset_id, 'FAIL'); RAISE;
- 你會得到一個錯誤,因為你在回滾後引發了異常。
這是一件好事!
你不希望異常無聲無息地消失,你想知道它。
您可以做的是處理您期望的異常。例如,如果您知道
ORA-06512
可能會發生並且您知道在這種情況下您需要做什麼,您可以為這種情況添加一個特定的處理程序,或者在您的儲存過程中,或者在呼叫它的程式碼中。