自治事务必须显式提交或回滚,否则抛出ORA-06519;仅可在存储过程、函数、包体、触发器中声明,不可嵌套;隔离性强,适合审计日志等独立持久化场景。
自治事务必须显式提交或回滚,否则会报 ORA-06519
声明了 pragma autonomous_transaction 的过程或函数,会脱离当前事务上下文独立运行。但它不会自动提交——哪怕只执行一条 insert,只要没写 commit 或 rollback,退出时 oracle 就会抛出 ora-06519: active autonomous transaction detected and rolled back。
常见错误是以为“自治”等于“自动提交”,结果调试时总卡在这儿。
- 所有自治事务块末尾必须有且仅有一次
COMMIT或ROLLBACK - 不能依赖外层事务的提交行为;外层回滚,不影响自治事务已提交的数据
- 如果逻辑可能分支(比如异常处理),确保每个出口路径都有提交/回滚,包括
EXCEPTION块里
只能在存储过程、函数、包体、触发器中声明,不能在匿名块或 SQL*Plus 脚本里用
PRAGMA AUTONOMOUS_TRANSACTION 是编译期指令,必须出现在可持久化存储单元的声明区(也就是 IS 或 AS 后面、BEGIN 前)。直接在 SQL*Plus 里写个匿名 BEGIN ... END; 块加这句,会报 PLS-00702: PRAGMA AUTONOMOUS_TRANSACTION must be declared in a subprogram。
- 支持的位置:包的过程/函数、独立过程/函数、触发器体、对象类型方法
- 不支持:SQL*Plus 匿名块、
DECLARE块、视图定义、函数内联表达式 - 想临时测试?先建个临时过程,别硬塞进脚本里
自治事务看不到外层未提交的变更,但外层能看见它已提交的数据
这是隔离性带来的典型现象。比如外层事务插入了一行但还没 COMMIT,此时调用自治过程记录日志,它查不到那行数据;而它自己插入的日志行,一旦 COMMIT,外层立刻能查到——哪怕外层最终 ROLLBACK 了。
- 适合场景:审计日志、错误跟踪、状态快照,即“不管主流程成败,这事我得记下来”
- 不适合场景:需要读取主事务中间态数据的校验逻辑
- 注意序列值:自治事务调用
NEXTVAL会真实推进序列,不可回滚
嵌套自治事务不被允许,重复声明会报 PLS-00703
一个已标记为自治的子程序里,不能再声明另一个自治事务。Oracle 不支持事务嵌套层级,哪怕只是“自治里再起一个自治”。编译时就会失败:
PLS-00703: multiple instances of AUTONOMOUS_TRANSACTION pragma
- 如果包里多个过程都需要自治,各自独立声明即可,但不要让它们互相调用还都标自治
- 特别警惕包体中过程 A 调用过程 B,A 和 B 都标了
PRAGMA AUTONOMOUS_TRANSACTION—— 这是无效组合 - 真需要多级独立事务?拆成不同包或独立过程,靠调用关系解耦,而不是靠嵌套声明
自治事务不是万能的事务开关,它解决的是“逃逸当前事务边界”的刚需,但也因此带来隔离、可见性、错误处理等一连串约束。最容易漏掉的是异常路径里的 ROLLBACK,一不留神就让日志写一半失败,还带崩整个调用链。

















