关于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的特性,一定能取得事倍功半的效果.

时间: 2024-10-16 01:19:18

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

Oracle与SQL自治事务

自治事务 自治事务是独立的事务操作,如果考虑到事务回滚,必须单独写成一个触发器来完成, 一个事务A在另一个事务B内被调用,那个事务A是自治事务,自治事务A执行过程中会脱离其session内未执行完毕的事务的影响. 如果session从B事务开始——A事务开始和结束——B事务结束 上述的A事务不受没有完成的B事务的影响,然后A事务执行完毕后再次回到B事务执行没有完成的B事务. 通过pragma autonomous_transaction将一个pl/sql程序结构设定为自治事务,pragma是编译

Oracle - 自治事务autonomous transaction

自治事务 - autonomous transaction 在Oracle数据库中,有时候我们会希望记录一个过程或者函数的运行日志,不管正常运行结束还是触发异常结束,都要记录. 正常结束的没有问题,但是触发异常的情况下,一般的过程或者函数显然不能在插入运行日志之后直接Commit,因为触发异常后相关业务逻辑需要RollBack. 而自治事务就能够很好的避免了这样的问题,就是说自治事务是在某个会话中独立开启一个事务,在其中处理的操作不会影响到同一会话中其他事务未提交的内容. 下面开始举个例子说明一

oracle 自治事物 -- autonomous transaction

一 使用规则 : 在begin 之前申明  : PRAGMA AUTONOMOUS_TRANSACTION; 二 使用理解:autonomous transaction 是一个独立的事务,这一点是理解autonomous transaction 的关键,虽然受main transaction 的调用.下面用一个例子来加深理解. 创建一个测试表,往其中插入两条记录,不提交,接着声明一个自治事务,在其中继续 往表中插入记录,并且在自治事务对插入的记录进行提交.我们从输出中可以知道main trans

Oracle的自治事务

自治事务(autonomous transaction)允许你创建一个"事务中的事务",它能独立于其父事务提交或回滚.利用自治事务,可以挂起当前执行的事务,开始一个新事务,完成一些工作,然后提交或回滚,所有这些都不影响当前所执行事务的状态.自治事务提供了一种用PL/SQL控制事务的新方法,可用于: 顶层匿名块: 本地(过程中的过程).独立或打包的函数和过程: 对象类型的方法: 数据库触发器. 使用例子演示自治事务如何工作 --创建测试表用于保存信息 [email protected]&

[转]oracle中使用set transaction设置事务属性

本文转自:http://yedward.net/?id=24 set transaction语句允许开始一个只读或者只写的事务,建立隔离级别或者是为当前的事务分配一个特定的回滚段.需要注意的是,set transaction必须是事务处理中的第一条语句,注意是事务处理的第一条语句,不是指代码的第一条语句,并且set transaction在一个事务中只能出现一次. set transaction的语法如下: SET TRANSACTION parameter; parameter是用来指定参数的

oracle:触发器,自治事务 trigger

create or replace trigger TRI_FC83_INSERT before insert ON FC83 FOR EACH ROW declare PRAGMA AUTONOMOUS_TRANSACTION; BEGIN :new.afc212 := '1'; delete from fc83 where afc001 = :new.afc001 and afa031 = :new.afa031 and afc210 = :new.afc210; commit; END T

Oracle自治事务实际用例

如下,新建两个存储过程: 在主自治事务中,我们插入一条记录,然后在自治事务中,查看表中行数,然后尝试插入三条记录,查看行数,最后rollback 查看行数,最后返回主事务,查看行数. 1.如下代码: --主事务 PROCEDURE p_test_at_and_mt IS cnt NUMBER := -1; BEGIN INSERT INTO msg VALUES ('father Record'); SELECT COUNT(*) INTO cnt FROM msg; dbms_output.p

Oracle 通过触发器 来创建 同步临时表 及处理 通过 自治事务 来解决 查询 基表的问题

// 触发器 create or replace trigger tr_sync_BD_MARBASCLASS after INSERT or UPDATE on BD_MARBASCLASS for each row declare v_cnt integer; PRAGMA AUTONOMOUS_TRANSACTION; -- 自治事务 begin /** * Name : tr_sync_BD_MARBASCLASS * Desc : 物料分类 增量同步 触发器 * Author : wu

oracle自治事务

自治事务的使用,独立于外层的事务控制 create or replace procedure insert_err_po( OrderNo number,CycleId number ) is pragma autonomous_transaction; begin insert into tt_err_po(po_num_id,cycle_num_id) values(OrderNo,CycleId); commit; end;