zoukankan      html  css  js  c++  java
  • (转)关于Oracle AUTONOMOUS TRANSACTION(自治事务)的介绍

    AUTONOMOUS TRANSACTION(自治事务)的介绍
      在基于低版本的ORACLE做一些项目的过程中,有时会遇到一些头疼的问题,比如想在执行当前一个由多个DML组成的transaction(事务)时,为每一步DML记录一些信息到跟踪表中,由于事务的原子性,这些跟踪信息的提交将决定于主事务的commit或rollback. 这样一来写程序的难度就增大了, 程序员不得不把这些跟踪信息记录到类似数组的结构中,然后在主事务结束后把它们存入跟踪表.哎,真是麻烦!
      有没有一个简单的方法解决类似问题呢?
      ORACLE8i的AUTONOMOUS TRANSACTION(自治事务,以下AT)是一个很好的回答。
      AT 是由主事务(以下MT)调用但是独立于它的事务。在AT被调用执行时,MT被挂起,在AT内部,一系列的DML可以被执行并且commit或rollback.
      注意由于AT的独立性,它的commit和rollback并不影响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 -> 主匿名块最后’看到’了所有的记录.
      
      从这个例子中,我们看到COMMIT和ROLLBACK的位置无论是在主匿名块中或者在子程序中,都会影响到整个当前事务.
      
      
      现在用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被暂停了. AT的COMMIT,ROLLBACK并不影响MT的执行.
      运用AT时,有一些注意事项,简单列举如下:
      1. 在匿名PL/SQL块中,只有顶级的匿名PL/SQL块可以被设为AT
      2. 如果AT试图访问被MT控制的资源,可能有deadlock发生.
      3. Package 不能被声明为AT,只有package所拥有的function和procedure 才能声明为AT
      4. AT程序必须以commit 或rollback结尾,否则会产生Oracle错误ORA-06519: active autonomous transaction detected and rolled back
      在程序开发时,如果充分运用AUTONOMOUS TRANSACTION的特性,一定能取得事倍功半的效果.

    原文地址:http://blog.sina.com.cn/s/blog_66cd71d90100shw7.html

  • 相关阅读:
    仿佛看到了曾经在电子厂的自己
    TP5 condition 多个条件如何写
    电子数据时代我该如何保存我的数据?
    Shell脚本查询磁盘数量
    缺少维生素?
    html5的页面在IOS中,按钮 变成圆角怎么办?
    生物信息数据分析准则
    用variant的数据来推导基因表达 | Imputation of Expression Using PrediXcan
    Rare-Variant Association Analysis | 罕见变异的关联分析
    英语语法
  • 原文地址:https://www.cnblogs.com/yanxin880526/p/5584377.html
Copyright © 2011-2022 走看看