oracle事务_笔记8:何时使用自治事务?
何时使用自治事务
Oracle数据库在内部支持自治事务时间已经不短了。我们看到的一直都是以递归SQL形式出现的自治事务。例如,从一个序列选择时就可以完成一个递归事务,从而在SYS.SEQ$表中立即递增序列。为支持你的序列,SYS.SEQ$表的更新会立即提交,并对其他事务可见,但是此时你的事务(即父事务)尚未提交。
另外,如果回滚你的事务,序列的递增仍会保留;它没有随父事务回滚,因为这部分工作已经提交。空间管理、审计以及其他内部操作都是以类似的递归方式完成的。
自治事务的一种可能合法的使用是用于定制审计。数据库中要对信息完成审计,与编写定制的触发器相比,还有许多更高效的方法。例如,可以使用DBMS_FGA包或者只是使用AUDIT命令本身。
对此,应用开发人员经常问:“用什么办法可以将PL/SQL例程中的错误记入日志,使得这些错误能够持久存储,即使PL/SQL例程的工作回滚,它们也依然存在?”之前,介绍过PL/SQL语句是原子的,即它们要么完全成功,要么完全失败。如果记录PL/SQL例程中的一个错误,默认情况下,Oracle回滚语句时,也会回滚记入日志的错误信息。利用自治事务,可以改变这种行为,即使其余的部分工作回滚,错误日志信息仍能持久存储。
下面,首先建立后面将要使用的一个简单的错误日志表,记录错误的时间戳、错误消息和PL/SQL错误栈(找出错误源自哪里):
scott@ORCL>create table error_log
2 (ts timestamp,
3 err1 clob,
4 err2 clob)
5 /
Table created.
现在需要PL/SQL例程将错误记入这个表。可以使用以下这个小例子:
scott@ORCL>create or replace
2 procedure log_error
3 (p_err1 in varchar2,p_err2 in varchar2)
4 as
5 pragma autonomous_transaction;
6 begin
7 insert into error_log(ts,err1,err2)
8 values(systimestamp,p_err1,p_err2);
9 commit;
10 end;
11 /
Procedure created.
这个例程的“神奇之处”在第5行,使用了pragma autonomous_transaction指令,通知PL/SQL我们希望这个子例程开始一个新事务,在其中完成一些工作,然后提交,而不影响进程中当前的任何其他事务。第9行的COMMIT只会影响这个LOG_ERROR过程完成的SQL。
现在来做个测试。我们创建两个相互调用的过程:
scott@ORCL>create table t(x int check(x>0));
Table created.
scott@ORCL>create or replace procedure p1(p_n in number)
2 as
3 begin
4 --some code here
5 insert into t(x) values(p_n);
6 end;
7 /
Procedure created.
scott@ORCL>create or replace procedure p2(p_n in number)
2 as
3 begin
4 --code
5 --code
6 p1(p_n);
7 end;
8 /
Procedure created.
然后从一个匿名块调用这些例程:
scott@ORCL>begin
2 p2(1);
3 p2(2);
4 p2(-1);
5 exception
6 when others
7 then
8 log_error(sqlerrm,dbms_utility.format_error_backtrace);
9 RAISE;
10 end;
11 /
begin
*
ERROR at line 1:
ORA-02290: check constraint (SCOTT.SYS_C0013864) violated
ORA-06512: at line 9
代码失败了(希望返回这个错误,所以第9行有一个RAISE)。我们可以验证Oracle确实取消了我们之前的工作(我们知道前两个对过程P2的调用已经成功,值1和2已经成功地插入到表T中):
scott@ORCL>select * from t;
no rows selected
不过,我们还可以验证错误日志信息得到持久存储,而且已经提交:
scott@ORCL>rollback;
Rollback complete.
scott@ORCL>select * from error_log;
TS
---------------------------------------------------------------------------
ERR1
--------------------------------------------------------------------------------
ERR2
--------------------------------------------------------------------------------
18-NOV-13 07.17.19.859564 PM
ORA-02290: check constraint (SCOTT.SYS_C0013864) violated
ORA-06512: at "SCOTT.P1", line 5
ORA-06512: at "SCOTT.P2", line 6
ORA-06512: at line 4
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5247.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
