zoukankan      html  css  js  c++  java
  • Oracle EBS 自治事务

    自治事务程序主要是自主性,那就是,独立于主要的事务。之所以独立,或者提交之后会影响其他事务处理,本质在于它本身符合编译指令的规则,也就是说它属于在编译阶段就执行的指令,而不是在运行阶段执行的。

    当自治事务行使时,主要的事务处理是暂缓状态的。自治事务完全独立于主要的事务处理。他们不分享锁、资源或者是提交的独立性。自治事务处理不会影响主要的事务处理。

    当自治事务提交时,自治事务的改变会对其他的事物处理显而易见的。只有当它的隔离水平是READ COMMITTED(默认值)时,当它重新运行时对主要的事务处理而言是可见的。

    注意以下几点:

    编译指令在编译的时候就完成了,而不是在运行的时候完成的。他们经由编译器传递消息;

    编译指示不能作用在整个包上,但是你可以作用在包里的每个子程序;

    编译指示不能作用整个object类型上,但是可以作用在每种SQL object 类型上;

    不像普通的触发器,一个自动触发器可以包含事务控制描述,像是提交和回滚,可以通过 EXECUTE IMMEDIATE 进行DDL操作,像是 create 或者 drop

    在主要的事务中,会滚到一个定位在自治事务子程序之前的保留点,是不会回滚掉自治事务。记住,自治事务是完全独立于主要事务的;

    如果一个自治事务尝试使用被主要事务处理占用的资源(只能当自治退出后才能重启),那么会造成死锁。数据库会抛出在自治事务的异常。如果异常无法处理那么会进行回滚;

    如果你在没有提交或者回滚是尝试退出一个活跃状态的自治事务,数据库会抛出异常。如果异常无法处理或者因为其他无法预料的异常事务处理结束,那么该事物会回滚;

    当你的自治事务是开启状态是你不能对你的自治规则执行管线 row声明。在执行管线 PIPE ROW声明钱你必须关掉自治事务。在执行 PIPE ROW 生命史提交或者回滚自治事务是普遍实现的。

    1. 自治事务方法

     

    CREATE OR REPLACE PACKAGE emp_actions AS  -- package specification
       FUNCTION raise_salary (emp_id NUMBER, sal_raise NUMBER)
         RETURN NUMBER;
    END emp_actions;
    /
    CREATE OR REPLACE PACKAGE BODY emp_actions AS  -- package body
    -- code for function raise_salary
       FUNCTION raise_salary (emp_id NUMBER, sal_raise NUMBER)
         RETURN NUMBER IS
         PRAGMA AUTONOMOUS_TRANSACTION;
         new_sal NUMBER(8,2);
       BEGIN
         UPDATE employees SET salary =
           salary + sal_raise WHERE employee_id = emp_id;
         COMMIT;
         SELECT salary INTO new_sal FROM employees
           WHERE employee_id = emp_id;
         RETURN new_sal;
       END raise_salary;
    END emp_actions;
    

      

    CREATE TABLE debug_output (msg VARCHAR2(200));
    
    -- create the package spec
    CREATE PACKAGE debugging AS
       FUNCTION log_msg (msg VARCHAR2) RETURN VARCHAR2;
       PRAGMA RESTRICT_REFERENCES(log_msg, WNDS, RNDS);
    END debugging;
    /
    -- create the package body
    CREATE PACKAGE BODY debugging AS
       FUNCTION log_msg (msg VARCHAR2) RETURN VARCHAR2 IS
          PRAGMA AUTONOMOUS_TRANSACTION;
       BEGIN
          -- the following insert does not violate the constraint
          -- WNDS because this is an autonomous routine
          INSERT INTO debug_output VALUES (msg);
          COMMIT;
          RETURN msg;
       END;
    END debugging;
    

      

     

    2. 自治事务过程

     

    CREATE PROCEDURE lower_salary (emp_id NUMBER, amount NUMBER) AS
      PRAGMA AUTONOMOUS_TRANSACTION;
    BEGIN
      UPDATE employees SET salary =
        salary - amount WHERE employee_id = emp_id;
      COMMIT;
    END lower_salary;
    

      

    DECLARE
       my_emp_id    NUMBER(6);
       my_last_name VARCHAR2(25);
       my_count     NUMBER;
    BEGIN
       my_emp_id := 120;
       SELECT debugging.log_msg(last_name)
         INTO my_last_name FROM employees
         WHERE employee_id = my_emp_id;
    -- even if you roll back in this scope, the insert into 'debug_output' remains
    -- committed because it is part of an autonomous transaction
       ROLLBACK;
    END;
    

      

     

    3. 自治事务块

     

     

     

    4. 自治事务触发器

     

    CREATE TABLE emp_audit ( emp_audit_id NUMBER(6), up_date DATE, 
                             new_sal NUMBER(8,2), old_sal NUMBER(8,2) );
    
    CREATE OR REPLACE TRIGGER audit_sal
       AFTER UPDATE OF salary ON employees FOR EACH ROW
    DECLARE 
       PRAGMA AUTONOMOUS_TRANSACTION;
    BEGIN
    -- bind variables are used here for values
       INSERT INTO emp_audit VALUES( :old.employee_id, SYSDATE, 
                                     :new.salary, :old.salary );
      COMMIT;
    END;
    

      

     

    下面拿一个例外举例说明一下事务处理的用途。

    例外声明关联着用户定义的例外名称和 oracle数据库的错误编码。你可以拦截任何oracle数据量的错误数字然后写一个例外处理他,而不是使用others处理。

    其中的错误数据是指错误数字任何有效的oracle 数据库错误数字,这些同方法 SQLCODE 返回的错误数字相同(通常是负数)。例外名称是指例外名称是指定义这个声明是一个编译指示。编译指示在编译是处理,而不是在运行时间时处理。这一点和自治事务运行一样。

    下面的例子展示了你可以执行一个DML操作返回的数字,而不是一些操作碰到错误的时候停下来。这个例子中例外是 ORA-24381

    在执行是所有的抛出的意外被保存在游标attribute %BULK_EXCEPTIONS 。每一个记录有两块。

    %BULK_EXCEPTIONS(i).ERROR_INDEX 存储的是在异常被抛出是后的 FORALL声明中的循环;

    %BULK_EXCEPTIONS(i).ERROR_CODE 中存储的是 ORACLE 数据库相关的错误编码;

    例外的个数被保存在%BULK_EXCEPTIONS.COUNT ,他计数从1开始。

    个体的错误信息或者任何可替代的参数,不被保存。但是错误信息可使用 ERROR_CODE 看到。

    在如下例子里,plsql抛出了一个定义好的异常,因为更新数据太大对于将数据插入到job_id列。在FORALL声明后 SQL%BULK_EXCEPTIONS.COUNT 返回2. SQL%BULK_EXCEPTIONS 内容是 (7,12899) and (13,12899)

     

     

    DECLARE
       deadlock_detected EXCEPTION;
       PRAGMA EXCEPTION_INIT(deadlock_detected, -60);
    BEGIN
       NULL; -- Some operation that causes an ORA-00060 error
    EXCEPTION
       WHEN deadlock_detected THEN
          NULL; -- handle the error
    END;
    /
    -- Temporary table for this example:
    CREATE TABLE emp_temp AS SELECT * FROM employees;
    
    DECLARE
      TYPE empid_tab IS TABLE OF employees.employee_id%TYPE;
      emp_sr empid_tab;
    
      -- Exception handler for ORA-24381:
      errors     NUMBER;
      dml_errors EXCEPTION;
      PRAGMA EXCEPTION_INIT(dml_errors, -24381);
    BEGIN
      SELECT employee_id
          BULK COLLECT INTO emp_sr FROM emp_temp
            WHERE hire_date < '30-DEC-94';
    
      -- Add '_SR' to job_id of most senior employees:
      FORALL i IN emp_sr.FIRST..emp_sr.LAST SAVE EXCEPTIONS
        UPDATE emp_temp SET job_id = job_id || '_SR' 
          WHERE emp_sr(i) = emp_temp.employee_id;
      -- If errors occurred during FORALL SAVE EXCEPTIONS,
      -- a single exception is raised when the statement completes.
    
    EXCEPTION
      -- Figure out what failed and why
      WHEN dml_errors THEN
       errors := SQL%BULK_EXCEPTIONS.COUNT;
       DBMS_OUTPUT.PUT_LINE
         ('Number of statements that failed: ' || errors);
       FOR i IN 1..errors LOOP
          DBMS_OUTPUT.PUT_LINE('Error #' || i || ' occurred during '||
             'iteration #' || SQL%BULK_EXCEPTIONS(i).ERROR_INDEX);
          DBMS_OUTPUT.PUT_LINE('Error message is ' ||
            SQLERRM(-SQL%BULK_EXCEPTIONS(i).ERROR_CODE));
       END LOOP;
    END;
    /
    DROP TABLE emp_temp;
    
    The output from the example is similar to:
    
    Number of statements that failed: 2
    Error #1 occurred during iteration #7
    Error message is ORA-12899: value too large for column
    Error #2 occurred during iteration #13
    Error message is ORA-12899: value too large for column
    

      

     

  • 相关阅读:
    JAVA帮助文档全系列 JDK1.5 JDK1.6 JDK1.7 官方中英完整版下载
    Apache HttpComponents Client 4.0快速入门/升级-2.POST方法访问网页
    HttpClient_4 用法 由HttpClient_3 升级到 HttpClient_4 必看
    Eclipse中设置编码的方式
    javadoc简介
    正则表达式:网页爬虫:从TXT中获取邮箱地址(获取的练习,缺点:一行只能匹配一个)
    Linux系统中yum 命令讲解
    查看CentOS版本信息
    Linux系统下安装JDK
    Linux基础性笔记
  • 原文地址:https://www.cnblogs.com/jenrry/p/10021227.html
Copyright © 2011-2022 走看看