この文章は Salesforce 機械翻訳システムを使用して翻訳されました。詳細はこちらをご参照ください。
英語に切り替える

トランザクションの制御

すべての要求は、Apex コードを実行するトリガ、クラスメソッド、Web サービス、Visualforce ページ、または匿名ブロックによって区切られます。要求全体が正常に完了した場合、すべての変更はデータベースに確定されます。たとえば、Visualforce ページが Apex コントローラをコールしたことにより、さらに Apex クラスがコールされたとします。すべての Apex コードの実行が完了し、Visualforce ページの実行が完了したときに、変更がデータベースに確定されます。要求が正常に完了しなかった場合は、データベースへのすべての変更はロールバックされます。

場合によっては、ビジネスルールによってレコードの処理中に作業の一部 (すでに実行された DML ステートメント) を「ロールバック」してその処理を別の指示のもとで続行できるようにする必要があります。Apex では、savepoint を生成できます。これは要求中のある時点を示し、その時点でのデータベースの状態を指定します。savepoint の後にある DML ステートメントを破棄して、savepoint の生成時点と同じ状況にデータベースを復元できます。

次の制限事項は、savepoint 変数の生成とデータベースのロールバックに適用されます。

  • 複数の savepoint を設定し、生成した最新 savepoint ではない savepoint にロールバックすると、ロールバックされた savepoint 変数は無効になります。たとえば、最初に savepoint SP1 を生成し、次に savepoint SP2 を生成した場合、SP1 にロールバックすると、変数 SP2 は無効になります。その変数を使用しようとすると、ランタイムエラーが発生します。
  • 各トリガ呼び出しが新しいトリガコンテキストであるため、savepoints への参照は、トリガ呼び出しを通過することはできません。静的変数として savepoint を宣言し��トリガコンテキスト全体で使用しようとすると、ランタイムエラーが発生します。
  • 設定した各セーブポイントは、DML ステートメントのガバナ制限にカウントされます。
  • ロールバック中、静的変数は戻されません。トリガの実行を再試行する場合、静的変数には最初の実行から得た値が維持されます。

  • 各ロールバックは、DML ステートメントのガバナ制限にカウントされます。データベースをそれ以上の回数ロールバックしようとすると、ランタイムエラーが発生します。
  • savepoint の設定後に挿入された sObject の ID は、ロールバック後にクリアされません。ロールバック後に挿入するには、sObject を作成します。ロールバック前に作成した変数を使用して sObject を挿入しようとすると、その sObject 変数には ID があるため失敗します。同じ変数を使用して sObject を更新または更新/挿入しようとした場合も、sObject はデータベース内に存在せず、更新できないため失敗します。

setSavepointrollback データベースメソッドの使用例を次に示します。

1Account a = new Account(Name = 'xxx'); insert a;
2System.assertEquals(null, [SELECT AccountNumber FROM Account WHERE Id = :a.Id].
3                           AccountNumber);
4
5// Create a savepoint while AccountNumber is null
6Savepoint sp = Database.setSavepoint();
7
8// Change the account number
9a.AccountNumber = '123';
10update a;
11System.assertEquals('123', [SELECT AccountNumber FROM Account WHERE Id = :a.Id].
12                             AccountNumber);
13
14// Rollback to the previous null value
15Database.rollback(sp);
16System.assertEquals(null, [SELECT AccountNumber FROM Account WHERE Id = :a.Id].
17                            AccountNumber);