在触发器中操作触发此触发器的表,用pragma autonomous_transaction选项。
1、为何使用自治事务
无法回滚的审计 : 一般情况下利用触发器禁止某些对表的更新等操作时,若记录日志,则触发器最后抛出异常时会造成日志回滚。利用自治事务可防止此点。
避免变异表: 即在触发器中操作触发此触发器的表
在触发器中使用ddl 写数据库:对数据库有写操作(insert、update、delete、create、alter、commit)的存储过程或函数是无法简单的用sql来调用的,
此时可以将其设为自治事务,从而避免ora-14552(无法在一个查询或dml中执行ddl、commit、rollback)、ora-14551(无法在一个查询中执行dml操作)等错误。
需要注意的是函数必须有返回值,但仅有in参数(不能有out或in/out参数)。
开发更模块化的代码: 在大型开发中,自治事务可以将代码更加模块化,失败或成功时不会影响调用者的其它操作,
代价是调用者失去了对此模块的控制,并且模块内部无法引用调用者未提交的数据。
2、如何工作
事务控制
declare整个块都是属于父事务的,自治事务从离pragma后的第一个begin开始,只要此begin块仍在作用域,则都属于自治事务。
例如在declare模块中声明一个写数据库的函数,则此函数虽然在自治事务所在存储过程执行,但其属于父事务;而自治事务中调用的任何函数和存储过程、激发的任何触发器等均为此自治事务的一部分。
自治事务可以嵌套,嵌套深度等只受init.ora参数transactions(同时并发的事务数,缺省为sessions的1.1倍)制约。
作用域
2.1 包中的变量
自治事务可看到并修改父事务的变量,父事务也会察觉到这一改变,且不存在回滚问题。
2.2 会话设置/参数
自治事务与父事务共享同一个会话环境,通过alter session作的修改对整个会话均有效。但set transaction是事务级的,仅对提起修改的事务有效。
2.3 数据库修改
父事务已提交的修改对自治事务可见,未提交的对自治事务不可见,自治事务的修改对父事务是否可见取决于隔离级别(isolation level)。
对于游标,取决于其打开的位置,若其在父事务中打开,则之前父事务未提交的修改对其是有效的,在自治事务中这些修改也可见;而在自治事务中打开,则父事务未提交的修改不可见。
若使用缺省的read committed隔离级别,则自治事务的修改对父事务可见;若改用serializable,则不可见。
2.4 锁
父事务与自治事务是完全不同的事务,因此无法共享锁等。
结束一个自治事务必须提交一个commit、rollback或执行ddl。
保存点无法在自治事务中回滚到父事务中的一个保存点,只能在内部使用保存点。
3、最后说明 不支持分布式事务截至8.1.7在自治事务中不支持分布式事务
仅可用pl/sql 全部事务回滚若自治事务出错,则全部回滚,即便父事务有异常处理模块。
事务级临时表每个会话仅一个事务可访问事务级临时表(多个会话中的事务可并发操作)。
4、可能遇到的错误
ora-06519 – 检查到活动自治事务,回滚——退出自治事务时没有提交、回滚或ddl操作
ora-14450 – 试图访问正在使用的事务级临时表
ora-00060 – 等待资源时检查到死锁
本文来自csdn博客,转载请标明出处:
http://blog.csdn.net/alex197963/archive/2008/01/11/2036500.aspx