自治事务,是独立于普通事务的一致性外,可以单独开辟的一个事务。即本事务提交或回滚,都不影响自治事务的提交和回滚。

这里举一例说明,自治事务记录报错信息的好处。

报错往往会中断,导致事务回滚,原来的报错触发条件便不可查询,我做了一个存储过程,在其他存储过程或触发器的exception里面调用这个段存储过程,便会将错误信息插入一张错误日志表。

存储过程如下: 

 

 
  
  1. create or replace procedure test.P_CHECK_ERRLOG(v_prog  in  varchar2 default '未声明程序名称'
  2.                                            v_oraerr in  varchar2 default '未声明ORA报错信息'
  3.                                            v_keyname in  varchar2 default '未声明关键字段'
  4.                                            v_keyval in varchar2 default '未声明自关键值'
  5.                                            v_cus  in   varchar2 default '未声明自定义信息'
  6.                                            v_errlvl in  varchar2 default 'WARNING'
  7.                                            v_memo in   varchar2 default '未声明备注'is 
  8.                                              PRAGMA AUTONOMOUS_TRANSACTION; 
  9. begin 
  10. insert into test.check_errlog 
  11.   (programname, oraerr, keyname, keyvalue, customermes, Errlvl, memo) 
  12. values 
  13.   (v_prog, v_oraerr, v_keyname, v_keyval, v_cus, v_errlvl, v_memo); 
  14. commit
  15. end P_CHECK_ERRLOG; 


调用过程如下

 

 
  
  1. --trg部分省略
  2. begin 
  3.         INSERT INTO test.temp
  4.           (col_a,col_b) 
  5.         VALUES 
  6.           (:new.col_a,:new.col_b); 
  7.       exception 
  8.         when DUP_VAL_ON_INDEX then 
  9.           begin 
  10.             test.p_check_errlog(v_prog    => 'TRG_TEST'
  11.                                    v_oraerr  => sqlerrm, 
  12.                                    v_keyname => 'col_a'
  13.                                    v_keyval  => :NEW.col_a, 
  14.                                    v_memo    => '目标表重复,本表正常插入,line77'); 
  15.           end
  16.         when others then 
  17.           begin 
  18.             test.p_check_errlog(v_prog    => 'TRG_TEST'
  19.                                    v_oraerr  => sqlerrm, 
  20.                                    v_keyname => 'col_a'
  21.                                    v_keyval  => :NEW.col_a, 
  22.                                    v_cus     => 'col_b:' || :new.col_b, 
  23.                                    v_memo    => '异常插入,line85'); 
  24.           end
  25.           raise_application_error(-20002, '插入异常,请检查错误日志表'); 
  26.          
  27.       end

第一种情况,是忽略唯一性错误,自治事务会记录该信息。

第二种情况是记录错误信息,并声明报错,中断操作。


注意,如果是不同用户,需要显示赋权,

 

 
  
  1. grant execute on test.p_check_errlog to usera; 
  2.  
  3. grant insert on test.check_errlog to usera; 

才可以在触发器或存储过程里调用