Oracle
 sql >> Base de données >  >> RDS >> Oracle

BEGIN - END bloquer les transactions atomiques en PL/SQL

Tout d'abord, BEGIN..END ne sont que des éléments syntaxiques et n'ont rien à voir avec les transactions.

Deuxièmement, dans Oracle, toutes les instructions DML individuelles sont atomiques (c'est-à-dire qu'elles réussissent intégralement ou annulent toute modification intermédiaire lors du premier échec) (sauf si vous utilisez l'option EXCEPTIONS INTO, que je n'aborderai pas ici).

Si vous souhaitez qu'un groupe d'instructions soit traité comme une seule transaction atomique, procédez comme suit :

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;

De cette façon, toute exception entraînera l'annulation des instructions de ce bloc, mais toutes les instructions exécutées avant ce bloc ne sera pas annulé.

Notez que je n'inclus pas de COMMIT - généralement, je préfère que le processus d'appel émette le commit.

Il est vrai qu'un bloc BEGIN..END sans gestionnaire d'exception s'en chargera automatiquement pour vous :

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

Si une exception est déclenchée, toutes les insertions et mises à jour seront annulées ; mais dès que vous souhaitez ajouter un gestionnaire d'exceptions, il ne sera pas annulé. Je préfère donc la méthode explicite utilisant des points de sauvegarde.