トランザクションの補償

SQL スクリプトの補償トランザクションは、複合ステートメントの終了後にトランザクションの整合性を復元するために COMPENSATE 例外が呼び出す特別なハンドラーです。

備考

COMPENSATE 例外のハンドラーが存在すると、実行時に特別な動作が発生します。他の例外とは異なり、この例外は ELSE 句では処理できません。明示的にのみ処理できます。
COMPENSATE 例外は、複合ステートメントの終了後に発生する唯一の例外であるため、特別です。ステートメントが終了してから長時間呼び出すことができます。この例外は、コミット中に障害が発生した場合に、トランザクションのコントローラーまたはシステムによってトランザクションが明示的にロールバックされた場合に発生します。
COMPENSATE ハンドラーは、他の例外ハンドラーと同様に、ブロックが認識できるすべての変数にアクセスできます。これは、ブロックが終了した時点でのこれらの変数のコピーです。
ブロックの実行ごとに変数状態のこの追加のストレージを保持する必要があるため、補償は高価になる可能性があります。たとえば、ブロックが 1,000 回実行されたループで発生した場合、1,000 回の個別の補償状態を実行する必要があります。このため、COMPENSATE ハンドラーを注意深く監視してください。
ハンドラーの現在のローカル データ状態のみが保持されます。グローバル システム状態は保持されません。つまり、別のプロシージャを呼び出した場合、このブロックが最初に実行されたときと同じ状態になることはありません。このため、COMPENSATE ハンドラーで使用できるように、通常の実行中に必要な状態を変数にキャプチャする必要があります。

PROCEDURE p ( )
BEGIN INDEPENDENT TRANSACTION
  <statement>
END

以下の例では、挿入は自動的にコミットされます。

PROCEDURE p ( )
BEGIN INDEPENDENT TRANSACTION
  INSERT INTO /shared/T (name, score) VALUES ('Joe”, 123) ;
END

以下の例では、インサートは自動的にロールバックされます。

PROCEDURE p ( )
BEGIN INDEPENDENT TRANSACTION
  DECLARE my_exc EXCEPTION;
  INSERT INTO /shared/T (name, score) VALUES ('Joe”, 123) ;
  RAISE my_exec;
END

以下の例では、挿入は自動的にコミットされます。

PROCEDURE p ( )
BEGIN INDEPENDENT TRANSACTION
  DECLARE my_exc EXCEPTION;
  INSERT INTO /shared/T (name, score) VALUES ('Joe”, 123) ;
  RAISE my_exec;
  EXCEPTION
    ELSE
END