2012-08-28 4 views
6

Ich zweifle ein bisschen. Lassen Sie sich dieses Pakets der Verfahren übernehmen:autonome Transaktionsumfang und Fehlererhöhung

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; 

So, wie Sie Fehler in test2() gibt es zu sehen, die auf test() aufzurichten wird, und dann in den err_manager() Verfahren behandelt werden.

So habe ich 2 Fragen:

  1. , was den Umfang des err_manager ist()? Ist es immer noch innerhalb der autonomen Transaktion? Ich denke schon, da es nur ein Funktionsaufruf ist, aber ich möchte sicher sein
  2. was passiert, wenn Sie eine autonome Transaktion wegen einer Fehlererhebung auf höhere Ebenen brutal beenden, ohne irgendeine Art von Commit oder Rollback durchzuführen?

Vielen Dank. S.

Antwort

9
  1. Der Transaktionsbereich der Ausführung des err_manager Verfahren ist die anruf autonome Transaktion, Sie richtig sind.

    Prozeduren und Funktionen erben ihre aufrufenden Transaktionen, sofern sie nicht selbständige Transaktionen sind.

  2. Wenn eine autonome Transaktion einen nicht behandelten Fehler auslöst, werden die Änderungen zurückgesetzt, und der Fehler wird an die aufrufende Anwendung weitergegeben. Hier ist ein Test:

    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. 
    
+0

fantastisch, danke! – Sebas