Ten eerste, BEGIN..END
zijn slechts syntactische elementen en hebben niets te maken met transacties.
Ten tweede zijn in Oracle alle individuele DML-statements atomair (d.w.z. ze slagen ofwel volledig, ofwel worden eventuele tussentijdse wijzigingen bij de eerste fout teruggedraaid) (tenzij je de EXCEPTIONS INTO-optie gebruikt, waar ik hier niet op in zal gaan).
Als u wilt dat een groep verklaringen wordt behandeld als een enkele atomaire transactie, doet u zoiets als dit:
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;
Op die manier zorgt elke uitzondering ervoor dat de instructies in dit blok worden teruggedraaid, maar alle instructies die voorafgaand aan dit blok zijn uitgevoerd wordt niet teruggedraaid.
Merk op dat ik geen COMMIT opneem - meestal geef ik de voorkeur aan het aanroepende proces om de commit uit te geven.
Het is waar dat een BEGIN..END-blok zonder uitzonderingshandler dit automatisch voor u afhandelt:
BEGIN
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
END;
Als er een uitzondering wordt gemaakt, worden alle invoegingen en updates teruggedraaid; maar zodra u een uitzonderingshandler wilt toevoegen, wordt deze niet teruggedraaid. Dus ik geef de voorkeur aan de expliciete methode met savepoints.