【发布时间】:2018-09-20 11:59:49
【问题描述】:
如果我有一个 AUTONOMOUS_TRANSACTION 过程执行插入操作,然后它调用带有插入功能的过程,那么第二个过程是否需要提交,或者带有 AUTONOMOUS_TRANSACTION 的过程是否会处理提交?
【问题讨论】:
标签: plsql transactions commit
如果我有一个 AUTONOMOUS_TRANSACTION 过程执行插入操作,然后它调用带有插入功能的过程,那么第二个过程是否需要提交,或者带有 AUTONOMOUS_TRANSACTION 的过程是否会处理提交?
【问题讨论】:
标签: plsql transactions commit
答案是否定的。 “第二个”过程 - 由第一个调用 - 不必包含 COMMIT 语句。当您将此语句添加到过程或函数的声明部分时...
PRAGMA AUTONOMOUS_TRANSACTION;
然后适用以下规则:
在子程序可以关闭并将控制权传递回 调用块,在该子程序中所做的任何 DML 更改都必须是 提交或回滚。
如果有任何未保存的更改,PL/SQL 引擎将引发 ORA-06519 异常,如下所示:
CREATE OR REPLACE FUNCTION nothing RETURN INTEGER
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
UPDATE employees SET last_name = 'abc';
RETURN 1;
END;
/
BEGIN
DBMS_OUTPUT.put_line (nothing);
END;
/
ORA-06519: active autonomous transaction detected and rolled back
ORA-06512: at "STEVEN.NOTHING", line 10
ORA-06512: at line 2
好的,这就是基本的想法。现在让我们继续讨论具体问题。如果一个自治事务过程调用另一个过程,该过程不包括上面显示的 pragma 但执行 DML 语句并且不提交怎么办?我们会看到 ORA-06519 错误吗?下面的代码表明我们不会。
CREATE TABLE me_and_my_lovelies (name VARCHAR2 (100));
BEGIN
INSERT INTO me_and_my_lovelies VALUES ('Grandpa Steven');
INSERT INTO me_and_my_lovelies VALUES ('Loey');
INSERT INTO me_and_my_lovelies VALUES ('Juna');
COMMIT;
END;
/
CREATE OR REPLACE PROCEDURE not_auton_no_commit
AUTHID DEFINER
IS
BEGIN
UPDATE me_and_my_lovelies
SET name = UPPER (name);
END not_auton_no_commit;
/
CREATE OR REPLACE PROCEDURE auton_commit
AUTHID DEFINER
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
not_auton_no_commit ();
COMMIT;
END auton_commit;
/
BEGIN
auton_commit;
END;
/
SELECT COUNT(*) low_name
FROM me_and_my_lovelies
WHERE name <> UPPER (name)
/
LOW_NAME
--------
0
没有引发错误。所有行都已更新。所以让我们回到规则: 在关闭子程序并将控制权传递回调用块之前,必须提交或回滚在该子程序中所做的任何 DML 更改。
您可能会想:但是 UPDATE 语句(“DML 更改”)不是“在”auton_commit 中创建的。是和不是。是的,UPDATE 语句不是 auton_commit 文本的一部分。但是UPDATE语句是在auton_commit的范围内执行的。这才是最重要的。 auton_commit 执行的任何代码,无论是“直接”在其可执行部分中执行,还是通过调用另一个子程序“间接”执行,都是自治事务的一部分。
应用规则的唯一点是 PL/SQL 尝试关闭 auton_commit 并将控制权返回给外部块。
包含上述代码here的LiveSQL脚本。
更多关于自治事务的信息here。
注意:此问答摘自博客。全文here.
【讨论】: