Newer Version Available
ロックステートメント
Apex の FOR UPDATE では、レコードの更新中に sObject レコードをロックして、競合の条件やスレッドの安全性の問題の発生を回避できます。
sObject レコードがロックされると、他のすべてのクライアントとユーザは、コードまたは Salesforce ユーザインターフェースを使用して更新を行えません。レコードをロックしているクライアントは、レコードに対してロジックを実行し、更新を行うことができます。ロック中は、ロックされたレコードが別のクライアントによって変更されることはありません。トランザクションが完了するとロックが解除されます。
Apex の一連の sObject レコードをロックするには、インライン SOQL ステートメントの後に FOR UPDATE キーワードを埋め込みます。たとえば、次のステートメントでは 2 つの取引先を照会すると共に、返された取引先をロックします。
1Account [] accts = [SELECT Id FROM Account LIMIT 2 FOR UPDATE];ロックに関する考慮事項
- クライアントがレコードをロックしている間、そのクライアントは同一トランザクションでデータベースの項目値を変更できます。他のクライアントが同じレコードを更新するには、トランザクションが完了してレコードのロックが解除されるまで待機する必要があります。ロックされている間も、他のクライアントは同じレコードを照会できます。
- 別のクライアントが現在ロックしているレコードをロックしようとすると、プロセスはロックが解除されるまで待機した後で、新しいロックを取得します。ロックが 10 秒以内に解除されない場合は、QueryException を取得します。同様に、別のクライアントが現在ロックしているレコードを更新しようとし、ロックが 10 秒以内に解除されない場合は、DmlException を取得します。
- ロックされているレコードをクライアントが変更しようとした場合、update コールが行われてから短時間でロックが解除されれば、更新操作は成功する可能性があります。この場合、2 番目のクライアントがレコードの古いコピーを取得していると、ロックしていたクライアントが行った変更がこの更新によって上書きされる可能性があります。これを回避するには、2 番目のクライアントが最初にレコードをロックする必要があります。ロックプロセスは、SELECT ステートメントを使用してデータベースのレコードの最新のコピーを返します。2 番目のクライアントはこのコピーを使用して新しい更新を行うことができます。
- FOR UPDATE 句を介して Apex で取得されるレコードのロックは、コールアウトの実行時に自動的に解除されます。FOR UPDATE クエリが以前実行された可能性があるコンテキストでコールアウトを実行するときは注意してください。
- 1 つのレコードで DML 操作を実行すると、当該レコードのほか、関連レコードもロックされます。詳細は、「Record Locking Cheat Sheet」を参照してください。