Първо, BEGIN..END
са просто синтактични елементи и нямат нищо общо с транзакциите.
Второ, в Oracle всички отделни DML изрази са атомарни (т.е. те или успяват напълно, или отменят всички междинни промени при първата грешка) (освен ако не използвате опцията ИЗКЛЮЧЕНИЯ В, която няма да навлизам тук).
Ако искате група изрази да се третира като единична атомна транзакция, бихте направили нещо подобно:
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;
По този начин всяко изключение ще доведе до връщане на операторите в този блок, но всички оператори, които са били изпълнявани преди този блок няма да се връща назад.
Обърнете внимание, че не включвам COMMIT – обикновено предпочитам процеса на извикване, за да издаде комит.
Вярно е, че блок BEGIN..END без манипулатор без изключение автоматично ще се справи с това вместо вас:
BEGIN
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
END;
Ако бъде повдигнато изключение, всички вмъквания и актуализации ще бъдат върнати назад; но веднага щом искате да добавите манипулатор на изключение, той няма да се върне назад. Затова предпочитам изричния метод, използващ точки за запис.