昨天处理项目中的一个业务需求要用到触发器实现,触发器中涉及到在 inserting、deleting、updating以后来触发对表的操做,对于inserting、updating中的操做均可以正常实现,就是 deleting的时候,要求更新其余表,更新的值是对触发器表自身的查询操做,本人在有限的水平范围以内试过N中方式来达到需求,最后无果,无奈之下只 有找经理帮忙看看问题,最终问题被解决了,果真是用到了本身不太熟悉的oracle自治事务,并且这个自治事务由于是独立的事务操做,考虑到事务回滚,必 须单独写成一个触发器来完成,最后问题被老大解决掉了,每次问题但愿都是成长的机会,会有收获,因而乎就到网上找了下自治事务(简称AT)相关方面的说明 及用法,下午就到园子里来mark下,供本身学习及各位园友参考;html
一、自治事务使用状况sql
没法回滚的审计 : 通常状况下利用触发器禁止某些对表的更新等操做时,若记录日志,则触发器最后抛出异常时会形成日志回滚。利用自治事务可防止此点。
避免变异表: 即在触发器中操做触发此触发器的表
在 触发器中使用ddl 写数据库:对数据库有写操做(insert、update、delete、create、alter、commit)的存储过程或函数是没法简单的用 sql来调用的,此时能够将其设为自治事务,从而避免ora-14552(没法在一个查询或dml中执行ddl、commit、rollback)、 ora-14551(没法在一个查询中执行dml操做)等错误。须要注意的是函数必须有返回值,但仅有in参数(不能有out或in/out参数)。
开发更模块化的代码: 在大型开发中,自治事务能够将代码更加模块化,失败或成功时不会影响调用者的其它操做,代价是调用者失去了对此模块的控制,而且模块内部没法引用调用者未提交的数据。数据库
二、Oracle 自制事务是指的存储过程和函数能够本身处理内部事务不受外部事务的影响,用pragma autonomous_transaction来声明,要建立一个自治事务,您必须在匿名块的最高层或者存储过程、函数、数据包或触发的定义部分中,使用 PL/SQL中的PRAGMA AUTONOMOUS_TRANSACTION语句。在这样的模块或过程当中执行的SQL语句都是自治的。安全
create or replace procedure AutoNomouse_Insert is PRAGMA AUTONOMOUS_TRANSACTION;
begin
insert into Msg values('AutoNomouse Insert');
commit;
end;
三、自治事务能够嵌套,嵌套深度等只受init.ora参数transactions(同时并发的事务数,缺省为sessions的1.1倍)制 约。由于自治事务是与主事务(简称MT)相分离的,因此它不能检测到被修改过的行的当前状态。这就好像在主事务提交以前,它们一直处于单独的会话里,对自 治事务来讲,它们是不可用的。然而,反过来状况就不一样了:主事务可以检测到已经执行过的自治事务的结果。session
四、若是AT试图访问被MT控制的资源,可能有deadlock发生.Package 不能被声明为AT,只有package所拥有的function和procedure 才能声明为AT。主事务与自治事务是彻底不一样的事务,所以没法共享锁等。结束一个自治事务必须提交一个commit、rollback或执行ddl,不然会产生Oracle错误ORA-06519: active autonomous transaction detected and rolled back 。保存点没法在自治事务中回滚到父事务中的一个保存点,只能在内部使用保存点。并发
五、可能遇到的错误
ora-06519 – 检查到活动自治事务,回滚——退出自治事务时没有提交、回滚或ddl操做
ora-14450 – 试图访问正在使用的事务级临时表
ora-00060 – 等待资源时检查到死锁oracle