Först, BEGIN..END
är bara syntaktiska element och har inget med transaktioner att göra.
För det andra, i Oracle är alla individuella DML-satser atomära (dvs. de lyckas antingen till fullo eller återställer eventuella mellanliggande ändringar vid det första misslyckandet) (såvida du inte använder alternativet EXCEPTIONS INTO, som jag inte kommer att gå in på här).
Om du vill att en grupp uttalanden ska behandlas som en enda atomär transaktion, skulle du göra något så här:
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;
På så sätt kommer alla undantag att göra att satserna i detta block återställs, men alla satser som kördes före detta block kommer inte att återställas.
Observera att jag inte inkluderar en COMMIT - vanligtvis föredrar jag anropsprocessen för att utfärda commit.
Det är sant att ett BEGIN..END-block utan undantagshanterare kommer att hantera detta automatiskt åt dig:
BEGIN
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
END;
Om ett undantag görs kommer alla infogningar och uppdateringar att återställas; men så fort du vill lägga till en undantagshanterare återställs den inte. Så jag föredrar den explicita metoden med hjälp av räddningspunkter.