`

Oracle 嵌套事务与自治事务

 
阅读更多

一. 概念 
1. 嵌套事务(Nested Transaction): 
指在一个Parent事务中嵌套的一个或多个Sub Transaction.并且主事务与其相互影响,这种事务就称为嵌套事务。以Commit作为事务的结束。 
2. 自治事务(Autonomous Transaction): 
指在function,procedure等subprograms中对事务进行自治管理,当在别的pl/sql block里去调用这些subprograms的时候这些subprograms并不随着父pl/sql block的失败而回滚,而是自己管自己commit。以Commit作为事务的结束。自治事务常用于写入LOG或TRAC信息便于查找错误。 
二. 嵌套事务的运用(Nested Transaction) 
1.预备Create Table: 

Sql代码  收藏代码
  1. create table TEST_POLICY  
  2. (  
  3.   POLICY_CODE VARCHAR2(20),  
  4.   POLICY_TYPE CHAR(1)  
  5. )  

2.创建一个嵌套事务的procedure: 
1) 
Sql代码  收藏代码
  1. Procedure P_Insert_Policy(I_Policy_code varchar2(20),   
  2.                             I_Policy_type char(1)) as   
  3.   cnt number :=0;  
  4.   begin  
  5.       select count(1) into cnt from Test_Policy;  
  6.       Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  7.         
  8.       Insert into Test_Policy values(I_Policy_code, I_Policy_type);  
  9.       commit;--commit in nested transaction   
  10.   end P_Insert_Policy;  
  11. --call procedure used in nested transaction  
  12.   PROCEDURE TEST_PL_SQL_ENTRY(  
  13.                               I_POL_ID IN VARCHAR2,  
  14.                               O_SUCC_FLG OUT VARCHAR2) AS  
  15.   strSql varchar2(500);  
  16.   cnt number := 0;  
  17.   BEGIN  
  18.      delete from test_policy;  
  19.      commit;  
  20.      insert into test_policy values('2010042101''1');  
  21.      select count(1) into cnt from Test_Policy;  
  22.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  23.      --call nested transaction  
  24.      P_Insert_Policy('2010042102''2');  
  25.      rollback;--rollback data for all transactions  
  26.      commit;--master transaction commit  
  27.      select count(1) into cnt from Test_Policy;  
  28.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  29.      rollback;  
  30.        
  31.      select count(1) into cnt from Test_Policy;  
  32.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  33.        
  34. END TEST_PL_SQL_ENTRY;  
  35.   
  36. =>run Pl/sql:  
  37. records of the test_policy is 1 –-主事务中的操作已经commit  
  38. records of the test_policy is 1 –-主事务的操作对Nested transaction有影响。  
  39. records of the test_policy is 2 –-Nested transaction 已经Commit  
  40. records of the test_policy is 2 –-Nested transaction对主事务有影响。  

将上面的nested transaction的procedure修改一下,不需要commit: 
 
Sql代码  收藏代码
  1. Procedure P_Insert_Policy(I_Policy_code T_contract_master.Policy_Code%type,   
  2.                             I_Policy_type t_contract_master.policy_type%type) as   
  3.   cnt number :=0;  
  4.   begin  
  5.       select count(1) into cnt from Test_Policy;  
  6.       Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  7.         
  8.       Insert into Test_Policy values(I_Policy_code, I_Policy_type);  
  9.       --commit;  
  10.   end P_Insert_Policy;  
  11.   PROCEDURE TEST_PL_SQL_ENTRY(  
  12.                               I_POL_ID IN VARCHAR2,  
  13.                               O_SUCC_FLG OUT VARCHAR2) AS  
  14.   strSql varchar2(500);  
  15.   cnt number := 0;  
  16.   BEGIN  
  17.      delete from test_policy;  
  18.      commit;  
  19.      insert into test_policy values('2010042101''1');  
  20.      select count(1) into cnt from Test_Policy;  
  21.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  22.        
  23.      P_Insert_Policy('2010042102''2');  
  24.      rollback;  
  25.      commit;  
  26.      select count(1) into cnt from Test_Policy;  
  27.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  28.      rollback;  
  29.        
  30.      select count(1) into cnt from Test_Policy;  
  31.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  32.        
  33. END TEST_PL_SQL_ENTRY;  
  34. Run Pl/Sql=>  
  35. 结果是:  
  36. records of the test_policy is 1 –-主事务中的操作已经commit  
  37. records of the test_policy is 1 –-主事务的操作对Nested transaction有影响。  
  38. records of the test_policy is 0 –-Nested transaction 的数据被主事务rollback.  
  39. records of the test_policy is 0   


三.自治事务(Autonomous transaction) 
1.下面是来自于Oracle上对自治事务的描述: 
autonomous transactions  does not depend on the main transaction. For example, if the main transaction rolls back, nested transactions roll back, but autonomous transactions do not. 
autonomous transactions‘  committed changes are visible to other transactions immediately. (A nested transaction's committed changes are not visible to other transactions until the main transaction commits.) 

自治事务(以下简称AT)是由主事务(以下简称MT)调用但是独立于MT的事务。在自治事务被调用执行时,MT被挂起,在自治事务内部,一系列的DML可以被执行并且commit或rollback. 自治事务防止嵌套提交,使事务在自己的事务区内提交或回滚不会影响其他的事务。由于自治事务的独立性,它的commit和rollback并不影响MT的执行效果。在自治事务执行结束后,主事务获得控制权,又可以继续执行了。 
实现自治事务的定义,只需下列PL/SQL的声明部分加上PRAGMA AUTONOMOUS_TRANSACTION 就可以了。 
1). 顶级的匿名PL/SQL块 
2). Functions 或 Procedure. 

2.  定义一个自治事务: 
Sql代码  收藏代码
  1. Procedure p_insert_policy_new(i_policy_code Varchar2(20),  
  2.                                 i_policy_type char(1)) as  
  3.   Pragma Autonomous_Transaction;--define auto trans  
  4.   cnt number := 0;  
  5.   begin  
  6.       select count(1) into cnt from test_policy;  
  7.       Dbms_Output.put_line('records of the test policy table is: '||cnt);      
  8.         
  9.       Insert into Test_Policy values(I_Policy_code, I_Policy_type);                            
  10.       commit;  
  11.       select count(1) into cnt from test_policy;  
  12.       Dbms_Output.put_line('records of the test policy table is: '||cnt);   
  13.   end p_insert_policy_new;  
  14. --call auto trans procedure  
  15. PROCEDURE TEST_PL_SQL_ENTRY(  
  16.                               I_POL_ID IN VARCHAR2,  
  17.                               O_SUCC_FLG OUT VARCHAR2) AS  
  18.   strSql varchar2(500);  
  19.   cnt number := 0;  
  20.   v_policyCode t_contract_master.policy_code%type;  
  21.   BEGIN  
  22.      delete from test_policy;  
  23.      commit;  
  24.      insert into test_policy values('2010042101''1');  
  25.      select count(1) into cnt from Test_Policy;  
  26.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  27.        
  28.      p_insert_policy_new('2010042102''2');  
  29.      select count(1) into cnt from Test_Policy;  
  30.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  31.      rollback;  
  32.      select policy_code into v_policyCode from test_policy;  
  33.      Dbms_Output.put_line('policy_code: '|| v_policyCode);  
  34.      commit;  
  35.      select count(1) into cnt from Test_Policy;  
  36.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  37.      rollback;  
  38.        
  39.      select count(1) into cnt from Test_Policy;  
  40.      Dbms_Output.put_line('records of the test_policy is '|| cnt);  
  41.        
  42.   END TEST_PL_SQL_ENTRY;  
  43. Run pl/sql=>  
  44. records of the test_policy is 1 –-Master trans has been committed.  
  45. records of the test policy table is: 0 -–Auto trans isn’t affected by master trans.  
  46. records of the test policy table is: 1—-Auto trans has been committed.  
  47. records of the test_policy is 2  
  48. policy_code: 2010042102—-rollback affected master trans  
  49. records of the test_policy is 1   
  50. records of the test_policy is 1  


3 总结Auto Transaction: 

(1)其中 pragma 关键字的作用是通知 PL/SQL 编译器,将声明它的这个 PL/SQL 代码块分割为一个自治的或独立的事务。定义自治事务时,要遵守以下几条规则: 
1) 如果 PL/SQL 块是匿名的,那么该匿名 PL/SQL 块必须是一个顶层块。 
2) 如果 PL/SQL 块不是匿名的,那么它必须作为包或存储过程序单元一部分的一个过程或函数。当在包中定义自治事务时,只有包中具体的函数或过程才能被指定为自治的的。 
3) PL/SQL 块也可以是存储对象类型的一个方法 
4) PL/SQL 块也可以是一个数据库触发器 
(2)自治事务的一些关键问题 
1) 带 ALTER SESSION 的自治事务 
自治事务应该与主事务共享一个会话,因此通过 ALTER SESSION 语句,对该会话的任何修改,对自治事务和主事务应该都是可见的。但自治事务执行与主事务不同的上下文中。任何从自治块中引发的自治子程序调用都与自治事务共享相同的事务上下文。 

2) 自治事务与死锁 
必须以下面的这种方式定义自治事务: 
死锁在自治事务试图访问一个被主事务占用的资源时发生,这时主事务会挂起,直到自治事务结束。自治事务死等主事务释放资源,结果可能导致死锁。 

3) 定义自治事务的条件 
只有顶层匿名块才能包括 PRAGMA AUTONOMOUS_TRANSTRACTION 

4) COMMIT 或 ROLLBACK 行为与自治事务 
自治事务是以 commit 或 rollback 语句结束的。因此,应该在自治事务程序的内部显式地包含一个 commit 或 rollback 语句。如果没有这样做,任何一个未确定的事务都会回滚。这是一个事务级的回滚,而不是一个语句级的回滚。 

5) 异常与自治事务 
当自治事务以一个异常的方式退出时,就发生一个事务级的回滚,自治事务中所有未确定的改变都会回滚 . 

6) 多个自治事务 
一个自治事务的上下文中,初始化多个自治事务。可以在一个自治块内定义多个 commit 或 rollback 语句来完成这项任务,当包含一个 rollback 时,它就会属于当前事务,而不属于主事务。 

7) 自治事务的并发问题 
自治事务与主事务是并发运行的,初始化文件 init.ora 中的 transactions 参数决定着每个会话中并发事务的数量。 

8) 通过自治事务和从 SQL 中调用用户自定义函数 
通过自治事务,可以从 SQL 中调用用户自定义函数来执行 DML 操作。只需把用户自定义函数定义为自治事务,函数就变为可从 SQL 中调用的。 
9) 自治事务和隔离等级 
应该在自治事务中给出 commit 或 rollback 命令,一旦 commit 或 rollback 在自治事务内部执行,那些改变对主事务而言是可见。但是 oracle 也允许从主事务中通过设定主事务的隔离等级为 SERIALIZABLE ,而不是默认的 READ COMMITTED ,对主事务隐藏这些改变,这可以通过 Set TRANSCTION 语句完成,其语法如下: 
Set transaction isolation level serializable; 
关于隔离等级的问题,以下两点值得注意: 
a) 当自治事务以 commit 或 rollback 而结束时,由自治事务造成的改变对主事务以外的其它事务是可见的 . 
b) 设置隔离等级为 serializable ,对主事务隐藏自治事务的变化。直到主事务提交,主事务一旦提交,自治事务中的改变对自治事务也就可见。 

10)  隔离等级 
隔离等级是一种处理修改数据库事务的方法,它影响到一个事务中的改变对另一个事务的可见性。 SQL92 中定义了 4 种隔离级别即: 
Sql代码  收藏代码
  1. READ UNCOMMITTED   
  2.  REPEATABLE READ   
  3.  READ COMMOTTED   
  4.  SERIALIZABLE   

oracle 支持 READ COMMOTTED 和 SERIALIZABLE 两种隔离级别 
Read committed :这种设置是 oracle 默认的 , 它使 oracle 查询可以看到查询之前提交的数据。换句话说,这种模式的事务是基于每句一致的事务集的。 
Serializable : 这种设置意味着一个事务中的所有语句,都在操作一个事务开始时的数据库映像中,这意味着没有 commit 之前,当前事务都不能看到其它事务所提交的数据。 

分享到:
评论

相关推荐

    Oracle数据完整性嵌套事务调用分析研究

    Oracle 数据完整性嵌套事务调用分析研究 Oracle 数据库中,数据完整性是指数据的正确性、完整性和一致性。为了保护数据的完整性,我们可以使用多种方法,例如数据表的主键约束、外键约束、触发器等等。在处理数据...

    oracle_专家高级编程 中文 第八章

    - **自治事务定义**:自治事务是一种特殊的事务类型,它可以嵌套在另一个事务中运行,并且独立于外部事务。这意味着,无论外部事务是否成功,自治事务的结果都会被提交。 - **自治事务的作用**:自治事务主要用于...

    Oracle+10g应用指导与案例精讲

    对子程序的调用者权限、管道表函数、传递触发器标识:new和:old以及自治事务也给出了具体的解决方法。第8 章 LOB与面向对象的数据管理. 第9章 Oracle的监听器和网络设置。包括Oracle网络体系结构,Oracle Net参数文件...

    Oracle 10g应用指导

    对子程序的调用者权限、管道表函数、传递触发器标识:new和:old以及自治事务也给出了具体的解决方法。第8 章 LOB与面向对象的数据管理. 第9章 Oracle的监听器和网络设置。包括Oracle网络体系结构,Oracle Net参数文件...

    ORACLE9i_优化设计与系统调整

    §14.8.1 嵌套连接- 181 §14.8.2 合并连接- 183 第15章 使用优化器提示 183 §15.1 提示(Hint)概念 184 §15.1.1 提示的指定 184 §15.2 使用提示 185 §15.2.1 提示的指定 185 §15.2.1.1 ALL_ROWS 186 §15.2....

    Oracle SQL高级编程(资深Oracle专家力作,OakTable团队推荐)--随书源代码

    CruiseYoung提供的带有详细书签的电子... 14.12 自治事务 409 14.13 小结 413 第15章 测试与质量保证 415 15.1 测试用例 416 15.2 测试方法 417 15.3 单元测试 418 15.4 回归测试 422 15.5 模式修改 422 15.6...

    ORACLE核心应用技术研究.doc

    - 自治事务:在主事务内部,可以执行一个独立的、不依赖于主事务的子事务,其结果在主事务提交或回滚时不受影响。 - 分布式事务和两时期提交:在分布式数据库环境下,事务可能涉及多个数据库节点。两时期提交协议...

    Oracle专题培训.doc

    自治事务是嵌套在主事务中的独立事务,有自己的提交和回滚能力,不影响外部事务的状态。 这些Oracle专题培训的知识点覆盖了数据库管理和优化的关键方面,对于提升数据库性能和管理效率至关重要。

    基于PL_SQL语言实现数据验证平台中的事务处理.pdf

    此外,PL/SQL还支持自治事务,即在一个块结构内部独立于主事务的事务控制,这为处理复杂逻辑提供了灵活性。 通过这种方式,PL/SQL不仅简化了数据验证平台的架构,提升了系统的可靠性,也使得数据处理更加高效和可控...

    oracle chm帮助文件下载

    11. **自治事务**:在PL/SQL中,`AUTONOMOUS TRANSACTION`可以创建一个独立于当前事务的子事务,确保其操作不会被外部事务回滚。 12. **暂停指定时间**:`DBMS_LOCK.SLEEP`函数可以在PL/SQL中使进程暂停指定的秒数...

    PL/SQL用户指南与参考

    自治事务可以在不影响外部事务的情况下独立执行。 ##### 十、确保PL/SQL程序的向后兼容 遵循最佳实践可以确保程序的向后兼容性。 #### 第七章:控制PL/SQL错误 ##### 一、错误控制一览 错误控制是PL/SQL程序设计的...

    数据分析核心知识点总结 —— SQL.pdf

    - 自治事务:小型独立的事务。 **九、函数** 函数用于在SQL语句中执行特定的计算或操作。 1. **系统函数** - 字符函数:如LEN、UPPER、LOWER等。 - 数值函数:如SUM、AVG、MIN、MAX等。 - 时间函数:如DATE、...

    超级有影响力霸气的Java面试题大全文档

    面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。 4. 多态性:  多态性是指允许不同类的对象对同一消息作出响应。多态性包括参数化...

Global site tag (gtag.js) - Google Analytics