今天的学习中接触到了自治事务的概念,便在网上查找点资料来学习一下,感谢原作者。
自治事务:
一个事务A在另一个事务B内被调用,那个事务A是自治事务,自治事务A执行过程中会脱离其session内未执行完毕的事务的影响。
如果session从B事务开始——A事务开始和结束——B事务结束
上述的A事务不受没有完成的B事务的影响,然后A事务执行完毕后再次回到B事务执行没有完成的B事务。
通过pragma autonomous_transaction将一个pl/sql程序结构设定为自治事务,pragma是编译器指令,可以将procedure function package等顶级匿名块定义成自治的程序结构。
罗嗦了半天直接来测试下:
首先创建一个procedure—noautonomous_transaction01
Create or replace procedure noautonomous_transaction01 as
Begin
Insert into test01 select * from test01 where rownum=1;
Commit;
End;
Select count(*) from test01
Count(*)
————
25
发现此时test01有25条数据
declare
begin
Insert into test01 select * from test01 where rownum=1;
Noautonomous_transaction01;
Rollback;
End;
上述pl/sql程序块内嵌套了一个dml的procedure过程。执行pl/sql程序块结束后发现test01有27条数据,也就说明了procedure中的commit完成了上述procedure和pl/sql程序块的提交。最后的rollback也就没有任何效果。
非自治事务内的procedure中得commit或者rollback会影响前面所有dml的影响。
创建一个自治事务
Create Procedure的autonomous_transaction01
Create or replace procedure autonomous_transaction01 as pragma autonomous_transaction01;
Begin
Insert into test01select * from test01 where rownum=1;
Commit;
End;
Select count(*) from test01
Count(*)
——
25
此时test01有25条数据
在pl/sql程序块中调用自治事务autonomous_transaction01
Begin
Insert into test01 select * from test01 where rownum=1;
Autonomous_transaction01;
Rollback;
End;
自治事务内的commit只会影响自治事务内的没有提交的dml,调用自治事务完毕后又会回到调用自治事务的事务内,此时最后的rollback也只能回滚自治事务外的dml,所以此时的test01中还是只有25条数据。
自治事务与被调用事务完全独立,不能共享调用者事务使用的锁和其他资源,而且自治事务内还可以调用其他自治事务。
自治事务与其调用者可能会发生死锁,Oracle会检测此类死锁并返回错误信息。(自治事务较常见应用与事务日志。)