我是否需要在由自治事务过程调用的子程序中提交?

时间:2018-04-10 18:42:21

标签: plsql transactions commit

如果我有一个执行插入的AUTONOMOUS_TRANSACTION过程,然后调用带插入的过程,第二个过程是否需要提交,或者AUTONOMOUS_TRANSACTION的过程是否会处理提交?

1 个答案:

答案 0 :(得分:2)

答案是否定的。 “第二个”过程 - 由第一个过程调用 - 不必包含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

注意:此Q&amp; A取自博客。完整帖子here

相关问题