Pertama, BEGIN..END
hanyalah elemen sintaksis, dan tidak ada hubungannya dengan transaksi.
Kedua, di Oracle semua pernyataan DML individual bersifat atomik (yakni mereka berhasil sepenuhnya, atau mengembalikan perubahan perantara apa pun pada kegagalan pertama) (kecuali jika Anda menggunakan opsi PENGECUALIAN INTO, yang tidak akan saya bahas di sini).
Jika Anda ingin sekelompok pernyataan diperlakukan sebagai transaksi atom tunggal, Anda akan melakukan sesuatu seperti ini:
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;
Dengan begitu, pengecualian apa pun akan menyebabkan pernyataan di blok ini dibatalkan, tetapi semua pernyataan yang dijalankan sebelum blok ini tidak akan dibatalkan.
Perhatikan bahwa saya tidak menyertakan COMMIT - biasanya saya lebih suka proses pemanggilan untuk mengeluarkan komit.
Benar bahwa blok BEGIN..END tanpa penangan pengecualian akan secara otomatis menangani ini untuk Anda:
BEGIN
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
END;
Jika pengecualian muncul, semua sisipan dan pembaruan akan dibatalkan; tetapi segera setelah Anda ingin menambahkan penangan pengecualian, itu tidak akan dikembalikan. Jadi saya lebih suka metode eksplisit menggunakan savepoints.