X++ トランザクションの整合性

この記事では、X++ 言語でのトランザクションの整合性について説明します。

トランザクションの整合性を確認する手順を踏まなかった場合、データが破損する可能性があります。 少なくとも、システム上の同時ユーザーに関してスケーラビリティが低下する可能性があります。 forUpdate チェックと ttsLevel チェックの 2 つの内部チェック機能がトランザクションの安全性を保証します。

  • forUpdate チェックは、更新のために最初に選択されたレコードのみを更新または削除されるのを確認するのに役立ちます。 select ステートメント内の forUpdate キーワードまたはテーブル上の selectForUpdate メソッドのいずれかを使用することで、更新プログラムのレコードを選択することができます。
  • ttsLevel チェックは、レコードが更新のために選択されたのと同じトランザクション範囲内でのみ更新または削除できることを保証するのに役立ちます。

整合性を確保するために、次のステートメントを使用します。

  • ttsBegin – このステートメントは、トランザクションの開始位置を示します。 これにより、データの整合性が確保され、トランザクションが終了するまで (ttsCommit または ttsAbort を通じて) 実行されるすべての更新が一貫していることも保証します。
  • ttsCommit – このステートメントは、トランザクションの正常終了を示します。 トランザクションを終了してコミットします。 財務と運用アプリにより、確定されたトランザクションが意図に従って実行されます。
  • ttsAbort – このステートメントを使用すると、現在のトランザクションのすべての変更を明示的に破棄できます。 この場合、データベースは元の状態にロールバックされ、何も変更されていません。 この文は通常、ユーザーが現在のジョブを中断したいことを検出した場合に使用します。 ttsAbort ステートメントは、データベースが一貫していることを保証するのに役立ちます。

通常、ttsAbort の代わりに、例外処理を使用することをお勧めします。 throw ステートメントは、自動的に現在のトランザクションを中断します。 次の例が示すように、ttsBeginttsCommit の間の明細書には 1 つ以上のトランザクション ブロックを含めることができます。 そのような場合、最後の ttsCommit ステートメントが正常に終了するまでコミットされるものはありません。

ttsBegin;
    // Some statements.
    ttsBegin;
        // More statements.
    ttsCommit;
ttsCommit;

次の例では、レコードのセットを選択し、CustGroup フィールドを更新します。 このコードは、select ステートメントがレコードを返さない場合、例外をスローし ます。

Custtable custTable;
ttsBegin;
    select forUpdate custTable where custTable.AccountNum == '5000';
    custTable.CustGroup = '1';
    custTable.update();
ttsCommit;

forUpdate チェックにより拒否されたコードの例

この例では、forUpdate キーワードがないため、最初のエラーが発生します。

ttsBegin;
    select myTable; // Rejected by the forUpdate check.
    mytable.myField = 'xyz';
    myTable.update();
ttsCommit;

ttsLevel チェックにより拒否されたコードの例

この例では、更新のトランザクション スコープが、レコードが ttsCommit の更新用に選択されたトランザクション スコープとは異なるためにエラーが発生します。

ttsBegin;
    select forUpdate * from myTable;
    myTable.myField = 'xyz';
ttsCommit;

ttsBegin;
    myTable.update(); // Rejected by the ttsLevel check.
ttsCommit;