まず、BEGIN..END
単なる構文要素であり、トランザクションとは何の関係もありません。
次に、Oracle では、個々の DML ステートメントはすべてアトミックです (つまり、完全に成功するか、最初の失敗時に中間の変更をロールバックします) (EXCEPTIONS INTO オプションを使用しない限り、ここでは説明しません)。
ステートメントのグループを単一のアトミック トランザクションとして扱いたい場合は、次のようにします。
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;
例外が発生すると、すべての挿入と更新がロールバックされます。ただし、例外ハンドラーを追加するとすぐにロールバックされません。したがって、私はセーブポイントを使用した明示的な方法を好みます。