自治事务必须显式commit或rollback,否则退出时抛ora-06519;仅支持在过程、函数、触发器或包体声明区(is/as后、begin前)使用,不可用于匿名块;它独立于主事务,已提交数据对主事务可见,但不可见主事务未提交数据。

必须显式加 COMMIT 或 ROLLBACK,否则过程退出时抛 ORA-06519;不能放在匿名块里,只能用于过程、函数、触发器或包体。
自治事务声明位置必须在子程序声明区(IS/AS 后、BEGIN 前)
PL/SQL 编译器只允许在可持久化对象的声明部分写 PRAGMA AUTONOMOUS_TRANSACTION。常见错误是把它塞进 SQL*Plus 的 BEGIN ... END; 匿名块里,会直接报 PLS-00702。
- ✅ 支持的位置:
CREATE OR REPLACE PROCEDURE、FUNCTION、PACKAGE BODY、TRIGGER - ❌ 不支持的位置:
DECLARE块、SQL*Plus 脚本顶层、视图定义、内联函数调用中 - 临时测试?先建个临时过程,别硬改脚本里的匿名块
每个自治事务块末尾必须有且仅有一次 COMMIT 或 ROLLBACK
自治事务不会自动提交,哪怕只执行一条 INSERT。没写提交/回滚,退出时 Oracle 就强制回滚并抛出 ORA-06519: active autonomous transaction detected and rolled back。
- 分支逻辑(比如
IF判断或异常处理)必须确保所有出口路径都有提交或回滚 -
EXCEPTION块里也要写ROLLBACK,不能只靠BEGIN里的COMMIT - 外层事务的
COMMIT或ROLLBACK对它完全无效——它只认自己块内的控制语句
自治事务看不到主事务未提交的数据,但主事务能立刻看到它已提交的结果
这是隔离性带来的典型现象,不是 bug。比如主事务插入了一行但还没 COMMIT,此时调用自治过程查这张表,查不到那行;而自治过程自己插入的日志行,一旦 COMMIT,主事务立刻能 SELECT 到——哪怕主事务最终 ROLLBACK 了。
- 适合场景:审计日志、错误跟踪、状态快照(“不管主流程成败,这事我得记下来”)
- 不适合场景:需要校验主事务中间态数据的逻辑(比如“检查刚才插入的记录是否满足某约束”)
- 序列值会被真实推进:
NEXTVAL在自治事务里调用后不可回滚,主事务也拿不到这个值的“预占”效果
最容易被忽略的是异常分支的提交/回滚覆盖——尤其当自治过程里有多个 INSERT 且逻辑分叉时,漏掉某条路径的 ROLLBACK 就会卡在 ORA-06519 上,调试时容易误判成环境或权限问题。











