Oracle 的自治事务(Autonomous Transaction)是将一个主事务分割成几个子事务,在执行完子事务以后再继续执行主事务。这里的关键是,子事务是独立于主事务的,子事务中的 ROLLBACK 和 COMMIT 操作只
会影响子事务中的 DML 操作;同样,主事务中的 ROLLBACK 和 COMMIT 操作只会影响主事务中的 DML 操作,而不会影响子事务中的操作。在子事务中已经 COMMIT 的操作,不会被主事务中的 ROLLBACK 撤销。
可以在程序开头使用如下命令实现自治事务:
PRAGMA AUTONOMOUS_TRANSACTION;
定义自治事务必须遵循以下规则:
(1)如果要被定义为自治事务的程序是匿名的,那么它必须是一个最外层的程序块。
(2)如果要被定义为自治事务的程序不是匿名的,那么它必须是函数或者存储过程。在一个包中,只有其
中的函数或存储过程能够定义成自治事务。整个包不能声明为自治事务。
(3)一个对象的方法可以声明为自治事务。
(4)触发器可以声明为自治事务。
(5)内嵌程序块不能声明为自治事务。
需要注意的是,对于一个匿名的自治事务程序块来说,只有这个块的 BEGIN 和 END 之间的代码被看作是自治事务。
自治事务可以用来解决“ORA-14551: 无法在查询中执行 DML 操作”错误。触发器无法包含 COMMIT 语句,
除非有 PRAGMA AUTONOMOUS_TRANSACTION 标记。但是,只有触发中的语句才能被提交,主事务则不行。
--主事务
PROCEDURE p_test_at_and_mt IS
cnt NUMBER := -1;
BEGIN
INSERT INTO msg VALUES ('father Record');
SELECT COUNT(*) INTO cnt FROM msg;
dbms_output.put_line('主事务插入一行之后行数:' || cnt);
p_test_at_and_mt_son;
dbms_output.put_line('运行子自治事务之后,主事务的行数:' || cnt);
--COMMIT;
END p_test_at_and_mt;
--测试自治事务(子自治)
PROCEDURE p_test_at_and_mt_son IS
PRAGMA AUTONOMOUS_TRANSACTION;
cnt NUMBER := -1;
BEGIN
SELECT COUNT(*) INTO cnt FROM msg;
dbms_output.put_line('插入三条记录之前子自治事务行数:' || cnt);
ROLLBACK;
INSERT INTO msg VALUES ('son Record1');
INSERT INTO msg VALUES ('son Record2');
INSERT INTO msg VALUES ('son Record3');
SELECT COUNT(*) INTO cnt FROM msg;
dbms_output.put_line('插入三条记录之后子自治事务行数:' || cnt);
ROLLBACK;
SELECT COUNT(*) INTO cnt FROM msg;
dbms_output.put_line('Rollback之后,子自治事务行数:' || cnt);
--COMMIT;
END p_test_at_and_mt_son;