关于Oracle AUTONOMOUS TRANSACTION(自治事务)的介绍

AUTONOMOUS TRANSACTION(自治事务)的介绍
  
  AUTONOMOUS TRANSACTION(自治事务)的介绍

  在基于低版本的ORACLE做一些项目的过程中,有时会遇到一些头疼的问题,比如想在执行当前一个由多个DML组成的transaction(事务),为每一步DML记录一些信息到跟踪表中,由于事务的原子性,这些跟踪信息的提交将决定于主事务的commitrollback. 这样一来写程序的难度就增大了, 程序员不得不把这些跟踪信息记录到类似数组的结构中,然后在主事务结束后把它们存入跟踪表.,真是麻烦
!
  有没有一个简单的方法解决类似问题呢?

  ORACLE8iAUTONOMOUS TRANSACTION(自治事务,以下AT)是一个很好的回答。
  AT 是由主事务(以下MT)调用但是独立于它的事务。在AT被调用执行时,MT被挂起,在AT内部,一系列的DML可以被执行并且commitrollback.
  注意由于AT的独立性,它的commitrollback并不影响MT的执行效果。在AT执行结束后,主事务获得控制权,又可以继续执行了。

如何实现AT的定义呢?我们来看一下它的语法。其实非常简单。
  只需下列PL/SQL的声明部分加上PRAGMA AUTONOMOUS_TRANSACTION 就可以了。
  1 顶级的匿名PL/SQL
  2 Functions Procedure(独立声明或声明在package中都可)
  3 SQL Object Type的方法
  4 触发器。
  
  

  比如:
  在一个独立的procedure中声明AT
  
CREATE OR REPLACE PROCEDURE
  
Log_error(error_msg IN VARCHAR2(100))
  
IS
  
PRAGMA AUTONOMOUS_TRANSACTION;
  
BEGIN
  
Insert into Error_log values ( sysdate,error_msg);
  
COMMIT;
  
END;
  下面我们来看一个例子,(win2000 advanced server + oracle8.1.6 , connect as scott

  建立一个表:
  
create table msg (msg varchar2(120));
  首先,用普通的事务写个匿名PL/SQL块:

  declare
  
cnt number := -1; --} Global variables
  
procedure local is
  
begin
  
select count(*) into cnt from msg;
  
dbms_output.put_line('local: # of rows is '||cnt);
  

  
insert into msg values ('New Record');
  
commit;
  
end;
  

  
   begin
  
delete from msg ;
  
commit;
  
insert into msg values ('Row 1');
  
local;
  
select count(*) into cnt from msg;
  
dbms_output.put_line('main: # of rows is '||cnt);
  
rollback;
  
local;
  
insert into msg values ('Row 2');
  
commit;
  
local;
  
select count(*) into cnt from msg;
  
dbms_output.put_line('main: # of rows is '||cnt);
  
end;
  运行结果(注意打开
serveroutput)
  local: # of rows is 1 -> 子程序local中可以’看到’主匿名块中的uncommitted记录

  main: # of rows is 2 -> 主匿名块可以’看到’2条记录(它们都是被local commit掉的
)
  local: # of rows is 2 -> 子程序local首先’看到’2条记录,然后又commit了第三条记录

  local: # of rows is 4 -> 子程序local又’看到’了新增加的记录(它们都是被local commit掉的),然后又commit了第五条记录
  main: # of rows is 5 -> 主匿名块最后’看到’了所有的记录.
  

  从这个例子中,我们看到COMMITROLLBACK的位置无论是在主匿名块中或者在子程序中,都会影响到整个当前事务.
  

  
  现在用AT改写一下匿名块中的procedure local:
  
...
  
procedure local is
  
pragma AUTONOMOUS_TRANSACTION;
  
begin
  
...
  重新运行(注意打开
serveroutput)
  local: # of rows is 0 -> 子程序local中无法可以’看到’主匿名块中的uncommitted记录 (因为它是独立的
)
  main: # of rows is 2 -> 主匿名块可以’看到’2条记录,但只有一条是被
commited.
  local: # of rows is 1 -> 子程序local中可以’看到’它前一次commit的记录,但是主匿名块中的记录已经被提前rollback

  local: # of rows is 3 -> 子程序local 中可以’看到’3条记录包括主匿名块commit的记录
  main: # of rows is 4 ->主匿名块最后’看到’了所有的记录.
  很明显,AT是独立的,在它执行时,MT被暂停了. ATCOMMIT,ROLLBACK并不影响MT的执行
.
  运用AT,有一些注意事项,简单列举如下
:
  1. 在匿名PL/SQL块中,只有顶级的匿名PL/SQL块可以被设为
AT
  2. 如果AT试图访问被MT控制的资源,可能有deadlock发生
.
  3. Package 不能被声明为AT,只有package所拥有的functionprocedure 才能声明为
AT
  4. AT程序必须以commit rollback结尾,否则会产生Oracle错误
ORA-06519: active autonomous transaction detected and rolled back
  在程序开发时,如果充分运用AUTONOMOUS TRANSACTION的特性,一定能取得事倍功半的效果
.
  

  参考资料:
  
metalink.oracle.com
  oracle8i manual

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值