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

ロックステートメント

Apex の FOR UPDATE では、レコードの更新中に sObject レコードをロックして、競合の条件やスレッドの安全性の問題の発生を回避できます。

sObject レコードがロックされると、他のすべてのクライアントとユーザは、コードまたは Salesforce ユーザインターフェースを使用して更新を行えません。レコードをロックしているクライアントは、レコードに対してロジックを実行し、更新を行うことができます。ロック中は、ロックされたレコードが別のクライアントによって変更されることはありません。トランザクションが完了するとロックが解除されます。

Apex の一連の sObject レコードをロックするには、インライン SOQL ステートメントの後に FOR UPDATE キーワードを埋め込みます。たとえば、次のステートメントでは 2 つの取引先をクエリすると共に、返された取引先をロックします。
1Account [] accts = [SELECT Id FROM Account LIMIT 2 FOR UPDATE];

ロックを使用する SOQL クエリでは、ORDER BY キーワードを使用できません。

メモ

ロックに関する考慮事項

  • クライアントがレコードをロックしている間、そのクライアントは同一トランザクションでデータベースの項目値を変更できます。他のクライアントが同じレコードを更新するには、トランザクションが完了してレコードのロックが解除されるまで待機する必要があります。ロックされている間も、他のクライアントは同じレコードをクエリできます。
  • 別のクライアントが現在ロックしているレコードをロックしようとすると、プロセスはロックが解除されるまで待機した後で、新しいロックを取得します。ロックが 10 秒以内に解除されない場合は、QueryException を取得します。同様に、別のクライアントが現在ロックしているレコードを更新しようとし、ロックが 10 秒以内に解除されない場合は、DmlException を取得します。
  • ロックされているレコードをクライアントが変更しようとした場合、update コールが行われてから短時間でロックが解除されれば、更新操作は成功する可能性があります。この場合、2 番目のクライアントがレコードの古いコピーを取得していると、ロックしていたクライアントが行った変更がこの更新によって上書きされる可能性があります。これを回避するには、2 番目のクライアントが最初にレコードをロックする必要があります。ロックプロセスは、SELECT ステートメントを使用してデータベースのレコードの最新のコピーを返します。2 番目のクライアントはこのコピーを使用して新しい更新を行うことができます。
  • 1 つのレコードで DML 操作を実行すると、当該レコードのほか、関連レコードもロックされます。詳細は、「Record Locking Cheat Sheet」を参照してください。

Apex コードにロックを設定する場合は、慎重に行ってください。「デッドロックの回避」を参照してください。

警告