ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 关于oracle autonomous transaction

关于oracle autonomous transaction

原创 Linux操作系统 作者:pingley 时间:2012-05-16 23:00:40 0 删除 编辑
关于oracle autonomous transaction
 autonomous transaction 翻译成中文叫自治事务,多好的名字,一听名字就明白
大半的意思了。autonmous transaction 是一个独立的事务,是由于main transaction调用而产生的。
autonomous transaction的独立性
autonomous transaction 是一个独立的事务,这一点是理解autonomous transaction 
的关键,虽然受main transaction 的调用。下面用一个例子来加深理解。
创建一个测试表,往其中插入两条记录,不提交,接着声明一个自治事务,在其中继续
往表中插入记录,并且在自治事务对插入的记录进行提交。我们从输出中可以知道main
transaction 和 autonomous transaction 的控制是独立开来的。autonomous transaction
的提交不会提交main transaction ,main transaction 的回滚也不会影响到 autonomous 
transaction。
SQL> create table test_at(id number,name varchar2(20));
Table created.
SQL> insert into test_at values(1000,'oracle');
1 row created.
SQL> insert into test_at values(1001,'db2');
1 row created.
SQL> ed
Wrote file afiedt.buf
  1  declare
  2    pragma autonomous_transaction;
  3  begin
  4    for i in 1002 .. 1010 loop
  5    insert into test_at values(i,'redis');
  6    end loop;
  7    commit;
  8* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> select * from test_at;
        ID NAME
---------- ----------------------------------------
      1000 oracle
      1001 db2
      1002 redis
      1003 redis
      1004 redis
      1005 redis
      1006 redis
      1007 redis
      1008 redis
      1009 redis
      1010 redis
11 rows selected.
SQL> rollback;
Rollback complete.
SQL> select * from test_at;
        ID NAME
---------- ----------------------------------------
      1002 redis
      1003 redis
      1004 redis
      1005 redis
      1006 redis
      1007 redis
      1008 redis
      1009 redis
      1010 redis
9 rows selected.
autonomous transaction 与dead lock 
autonomous transaction 尝试lock main transaction lock 的资源的话,将会
发生死锁。main transaction 调用autonomous transaction 后会被挂起,但是
他所持有的资源还是保持着,这时候如果autonomous transaction 试图访问
main transaction 持有的资源。autonomous transaction 不可能请求的到,
所以autonomous transaction 不能继续下去,也就导致了main transaction
无法继续走。死锁就发生了。
SQL> ed
Wrote file afiedt.buf
  1  create or replace procedure p_at as
  2    pragma autonomous_transaction;
  3  begin
  4    update test_at
  5    set name = 'mysql'
  6    where name = 'redis';
  7    commit;
  8* end p_at;
SQL> /
Procedure created.
SQL> ed
Wrote file afiedt.buf
  1  begin
  2    update test_at
  3    set name = 'mysql'
  4    where name = 'redis';
  5    p_at;
  6    commit;
  7* end;
SQL> /
begin
*
ERROR at line 1:
ORA-00060: 等待资源时检测到死锁
ORA-06512: 在 "SYS.P_AT", line 4
ORA-06512: 在 line 5
autonomous transaction 与 rollback
autonomous transaction 中必须包括rollback,commit 。autonomous transaction 
出错的时候将会被回滚掉,即使有exception handle.
SQL> ed
Wrote file afiedt.buf
  1  declare
  2     pragma autonomous_transaction;
  3  begin
  4     update test_at
  5     set name = 'mysql'
  6     where name = 'redis';
  7* end;
SQL> /
declare
*
ERROR at line 1:
ORA-06519: 检测到活动的独立的事务处理, 已经回退
ORA-06512: 在 line 7
SQL> select * from test_at;
        ID NAME
---------- ----------------------------------------
      1002 redis
      1003 redis
      1004 redis
      1005 redis
      1006 redis
      1007 redis
      1008 redis
      1009 redis
      1010 redis
9 rows selected.
SQL> ed
Wrote file afiedt.buf
  1  declare
  2     pragma autonomous_transaction;
  3  begin
  4     update test_at
  5     set name = 'mysql'
  6     where name = 'redis';
  7  exception
  8     when others then
  9     dbms_output.put_line('Error!,rollback or commit.');
 10* end;
SQL> /
PL/SQL procedure successfully completed.
SQL>  select * from test_at;
        ID NAME
---------- ----------------------------------------
      1002 redis
      1003 redis
      1004 redis
      1005 redis
      1006 redis
      1007 redis
      1008 redis
      1009 redis
      1010 redis
9 rows selected.
autonomous transaction 的小运用
autonomous transaction 的独立性是非常重要的,可以使调用他的main transaction
不需要额外的事务控制语句来控制调用的模块,结合exception handle 可以实现简单的
日志登记功能。
SQL> ed
Wrote file afiedt.buf
  1  create table error_logs
  2  ( id number(10),
  3    user_name varchar2(30),
  4    timestamp timestamp,
  5*   error_msg varchar2(1000))
SQL> /
Table created.
SQL> alter table error_logs add constraint error_logs_pk primary key (id);
Table altered.
SQL> ed
Wrote file afiedt.buf
  1* create sequence error_logs_seq
SQL> /
Sequence created.
SQL> ed
Wrote file afiedt.buf
  1  create or replace procedure log_errors(error_message in varchar2) as
  2    pragma autonomous_transaction;
  3  begin
  4    insert into error_logs(id,user_name,timestamp,error_msg)
  5    values(error_logs_seq.nextval,user,systimestamp,error_message);
  6    commit;
  7* end log_errors;
SQL> /
Procedure created.
SQL> alter table test_at add constraint test_at_pk primary key (id);
Table altered.
SQL> ed
Wrote file afiedt.buf
  1  begin
  2    insert into test_at
  3    values(1010,'mysql');
  4    insert into test_at
  5    values(1011,'mssql');
  6  exception
  7    when others then
  8      log_errors(sqlerrm);
  9      rollback;
 10* end;
SQL> /
PL/SQL procedure successfully completed.
SQL> select * from test_at
  2  where id >= 1010;
        ID NAME
---------- ----------------------------------------
      1010 redis
SQL> select * from error_logs;
        ID USER_NAME  TIMESTAMP                            ERROR_MSG
---------- ---------- ------------------------------------ ----------------------------------------------
         1 SYS        16-5月 -12 10.44.16.316000 下午      ORA-00001: 违反唯一约束条件 (SYS.TEST_AT_PK)
小结:autonomous transaction 在pl/sql 编程中是比较重要的部分,也是比较容易出现问题的部分。虽然上面讨论了autonomous transaction 的几个方面,其实很多地方还可以继续深入,如果有兴趣可以自己找资料研究。不过我个人认为除非有需要,否则有些知识够用就好,人生有崖,学无涯啊。

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26110315/viewspace-729971/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-02-06

  • 博文量
    169
  • 访问量
    741718