6

少し疑問です。このパッケージの手順を想定してみましょう。

PROCEDURE ERR_MANAGER(I_ERRM IN VARCHAR2) IS
BEGIN
    ROLLBACK;
    --DO SOME STUFF
END ERR_MANAGER;

PROCEDURE test IS 
    PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN

    test2;
    COMMIT;
EXCEPTION WHEN OTHERS THEN ERR_MANAGER(SQLERRM);
END test;


PROCEDURE test2 IS
BEGIN

    --DO SOME TRANSACTIONNAL DML

    RAISE_APPLICATION_ERROR(-20001, 'ERR'); --for the test purpose, in reality this could be any actual error

END test2;

したがって、ご覧のとおり、にエラーがありtest2()、これはになりtest()、メソッドで処理されerr_manager()ます。

だから私は2つの質問があります:

  1. err_manager()のスコープは何ですか?それはまだ自律トランザクション内にありますか?関数呼び出しにすぎないのでそうだと思いますが、必ず確認したいのですが
  2. エラーが上位レベルに上がったために、コミットやロールバックを一切行わずに、自律型トランザクションを残酷に終了するとどうなりますか?

どうもありがとうございます。S。

4

1 に答える 1

10
  1. err_managerプロシージャの実行のトランザクションスコープは、自律型トランザクションの呼び出しです。正解です。

    プロシージャと関数は、それ自体が自律型トランザクションでない限り、呼び出し元のトランザクションを継承します。

  2. 自律型トランザクションで未処理のエラーが発生すると、その変更がロールバックされ、エラーが呼び出し元のアプリケーションに伝播します。テストは次のとおりです。

    SQL> CREATE TABLE t (id number);
    
    Table created.
    
    SQL> DECLARE
      2     l NUMBER;
      3     PROCEDURE p IS
      4        pragma autonomous_transaction;
      5     BEGIN
      6        insert into t values (1);
      7        raise_application_error(-20001, 'rollback?');
      8     END;
      9  BEGIN
     10     p;
     11  EXCEPTION
     12     WHEN OTHERS THEN
     13        DBMS_OUTPUT.put_line('error catched:' || sqlcode);
     14        SELECT COUNT(*) INTO l FROM t;
     15        DBMS_OUTPUT.put_line('lines in t: ' || l);
     16  END;
     17  /
    error catched:-20001
    lines in t: 0
    
    PL/SQL procedure successfully completed.
    
于 2012-08-28T14:03:39.540 に答える