まず、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;
例外が発生した場合、すべての挿入と更新がロールバックされます。ただし、例外ハンドラーを追加するとすぐに、ロールバックされません。したがって、セーブポイントを使用した明示的な方法を好みます。