Nejprve BEGIN..END
jsou pouze syntaktické prvky a nemají nic společného s transakcemi.
Za druhé, v Oracle jsou všechny jednotlivé příkazy DML atomické (tj. buď uspějí v plném rozsahu, nebo při prvním selhání odvolají jakékoli mezilehlé změny) (pokud nepoužijete možnost EXCEPTIONS INTO, kterou zde nebudu rozebírat).
Pokud chcete, aby se se skupinou příkazů zacházelo jako s jedinou atomickou transakcí, udělali byste něco takového:
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;
Tímto způsobem jakákoli výjimka způsobí, že příkazy v tomto bloku budou vráceny zpět, ale všechny příkazy, které byly spuštěny před tímto blokem nebude vrácena zpět.
Všimněte si, že nezahrnuji COMMIT - obvykle dávám přednost volajícímu procesu, aby vydal potvrzení.
Je pravda, že blok BEGIN..END bez obsluhy bez výjimky to automaticky zpracuje za vás:
BEGIN
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
END;
Pokud je vyvolána výjimka, všechny vložky a aktualizace budou vráceny zpět; ale jakmile budete chtít přidat obslužnou rutinu výjimky, nevrátí se zpět. Dávám tedy přednost explicitní metodě pomocí bodů uložení.