Oracle
 sql >> Database >  >> RDS >> Oracle

BEGIN - END blocca le transazioni atomiche in PL/SQL

Innanzitutto, BEGIN..END sono semplicemente elementi sintattici e non hanno nulla a che fare con le transazioni.

In secondo luogo, in Oracle tutte le singole istruzioni DML sono atomiche (cioè riescono completamente o ripristinano eventuali modifiche intermedie al primo errore) (a meno che tu non usi l'opzione EXCEPTIONS INTO, che non entrerò qui).

Se desideri che un gruppo di istruzioni venga trattato come una singola transazione atomica, faresti qualcosa del genere:

BEGIN
  SAVEPOINT start_tran;
  INSERT INTO .... ; -- first DML
  UPDATE .... ; -- second DML
  BEGIN ... END; -- some other work
  UPDATE .... ; -- final DML
EXCEPTION
  WHEN OTHERS THEN
    ROLLBACK TO start_tran;
    RAISE;
END;

In questo modo, qualsiasi eccezione comporterà il rollback delle istruzioni in questo blocco, ma tutte le istruzioni eseguite prima di questo blocco non verrà eseguito il rollback.

Nota che non includo un COMMIT - di solito preferisco il processo di chiamata per emettere il commit.

È vero che un blocco BEGIN..END senza un gestore di eccezioni gestirà automaticamente questo per te:

BEGIN
  INSERT INTO .... ; -- first DML
  UPDATE .... ; -- second DML
  BEGIN ... END; -- some other work
  UPDATE .... ; -- final DML
END;

Se viene sollevata un'eccezione, verrà eseguito il rollback di tutti gli inserimenti e gli aggiornamenti; ma non appena si desidera aggiungere un gestore di eccezioni, non verrà eseguito il rollback. Quindi preferisco il metodo esplicito che utilizza i punti di salvataggio.