Po pierwsze, BEGIN..END
są jedynie elementami składniowymi i nie mają nic wspólnego z transakcjami.
Po drugie, w Oracle wszystkie indywidualne instrukcje DML są atomowe (tzn. albo kończą się powodzeniem, albo cofają wszelkie pośrednie zmiany przy pierwszym niepowodzeniu) (chyba że używasz opcji EXCEPTIONS INTO, o której tutaj nie będę się zagłębiać).
Jeśli chcesz, aby grupa instrukcji była traktowana jako pojedyncza transakcja niepodzielna, możesz zrobić coś takiego:
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;
W ten sposób każdy wyjątek spowoduje wycofanie instrukcji w tym bloku, ale wszystkie instrukcje, które zostały uruchomione przed tym blokiem nie zostanie wycofana.
Zwróć uwagę, że nie dołączam COMMIT - zwykle wolę, aby proces wywołujący wydał zatwierdzenie.
Prawdą jest, że blok BEGIN..END bez obsługi wyjątków automatycznie obsłuży to za Ciebie:
BEGIN
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
END;
Jeśli zostanie zgłoszony wyjątek, wszystkie wstawki i aktualizacje zostaną wycofane; ale jak tylko będziesz chciał dodać obsługę wyjątków, nie zostanie ona wycofana. Dlatego wolę metodę jawną używającą punktów zapisu.