Cette information devrait être facile à trouver, mais je n’ai pas eu de chance.
Quand j'ai un BEGIN - END
bloque dans un fichier PL/SQL, se comporte-t-il comme une transaction atomique, essayant de s’engager en frappant le bloc END
et, en cas de problème, annule les modifications?
Sinon, comment puis-je m'assurer que le code à l'intérieur du bloc BEGIN-END se comporte comme une transaction atomique et comment le bloc se comporte-t-il "par défaut"?
EDIT: Je cours à partir d’une procédure stockée et j’utilise un bloc implicite, je pense.
D'abord, BEGIN..END
ne sont que des éléments syntaxiques et n’ont rien à voir avec des transactions.
Deuxièmement, dans Oracle, toutes les instructions DML individuelles sont atomiques (c’est-à-dire qu’elles réussissent intégralement ou annulent les modifications intermédiaires lors du premier échec) (sauf si vous utilisez l’option EXCEPTIONS INTO, que je ne décrirai pas ici).
Si vous souhaitez qu'un groupe d'instructions soit traité comme une transaction atomique unique, 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 manière, toute exception entraînera l'annulation des instructions de ce bloc, mais toutes les instructions exécutées avant ce bloc ne seront pas annulées.
Notez que je n'inclus pas de COMMIT - en général, je préfère que le processus appelant lance le commit.
Il est vrai qu'un bloc BEGIN..END sans gestionnaire d'exception le gérera 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 les mises à jour seront annulées. mais dès que vous souhaitez ajouter un gestionnaire d'exceptions, il ne sera pas restauré. Donc, je préfère la méthode explicite utilisant des points de sauvegarde.
Les blocs BEGIN
-END
sont les blocs de construction de PL/SQL, et chaque unité PL/SQL est contenue dans au moins un de ces blocs. L'imbrication de blocs BEGIN
-END
au sein de blocs PL/SQL est généralement effectuée pour intercepter certaines exceptions et gérer cette exception spéciale, puis déclencher des exceptions non liées. Néanmoins, en PL/SQL, vous (le client) devez toujours émettre une validation ou une annulation pour la transaction.
Si vous souhaitez avoir des transactions atomiques dans une transaction contenant PL/SQL, vous devez déclarer un PRAGMA AUTONOMOUS_TRANSACTION
dans le bloc de déclaration. Cela garantira que tout DML dans ce bloc peut être validé ou annulé indépendamment de la transaction qui le contient.
Cependant, vous ne pouvez pas déclarer ce pragma pour les blocs imbriqués. Vous ne pouvez le déclarer que pour:
Référence: Oracle
Vous ne mentionnez pas s'il s'agit d'un bloc PL/SQL anonyme ou déclaratif, c'est-à-dire. Package, procédure ou fonction. Cependant, en PL/SQL, une COMMIT doit être faite explicitement pour enregistrer votre/vos transaction (s) dans la base de données. Le COMMIT enregistre toutes les transactions non enregistrées dans la base de données à partir de la session de votre utilisateur actuel .
Si une erreur se produit, la transaction effectue implicitement un ROLLBACK.
C'est le comportement par défaut pour PL/SQL.