Salesforceコラム
Salesforceに特化した情報をお届けします

Salesforceのfor updateとは?概要や使い方をご紹介

2021年08月12日

Salesforceのfor updateとは?


Salesforceのfor updateとは、sObjectレコードをロックして競合の条件や安全面を確保するするためのものです。

for updateを使用してsObjectをロックすると、他のすべてのユーザーやクライアントは、Salesforceユーザーインターフェースを使って更新を行うことができなくなります。

一方、レコードをロックしているクライアント側は、レコードにロジックを実行して更新を行うことができます。

ロック中は、ロックしているレコードが別のクライアントによって変更されることはありません。ロックしているクライアントのトランザクションが完了すると、レコードのロックが解除されます。

for updateの使い方

Salesforceのfor updateは、インラインSOQLステートメントの後に埋め込みます。

ApexコードでsObjectレコードをロックするには、インラインSOQLステートメントの後にfor updateキーワードを埋め込む必要があります。例えば、次のサンプルコードでは、2つの取引先を照会し、返された取引先レコードをロックしています。

ロックを使用する場合は、SOQLクエリでは「ORDER BY」キーワードを使用することができません。

ロックする際に考慮する点

Salesforceのfor updateを使用してsObjectをロックする際、いくつか考慮すべき点があります。

ロックしている間の他のクライアントの動作や、他のクライアントがロックをかけてきた場合の動作など、考慮する点がいくつかあるので以降に説明します。

ロック中の別クライアントの動作

Salesforceのfor updateを使用してsObjectをロックしている場合、別クライアントは同じレコードを更新することができません。

for updateを使用してロックしているクライアントは、同一トランザクションでデータベース項目の値を変更することができますが、他のクライアントは同じレコードを更新することができません。

他のクライアントが同じレコードを更新しようとした場合、トランザクションが完了してロックが解除されるまで待つ必要があります。ただし、ロックされている間でも、他のクライアントが同じレコードを参照することはできます。

ロック中に別クライアントがロックしようとした場合

Salesforceのfor updateを使用してsObjectをロックしているときに別のクライアントが同じレコードをロックした場合、ロック待機状態となります。

ロック待機状態となった後、ロックが解除されれば、新しいロックを取得することができます。ロック待機状態となった後、10秒以内にロックが解除されなかった場合は、QueryExceptionを取得します。

また、ロック状態のときに別クライアントがロック中のレコードを更新しようとして、10秒以内にロックが解除されなかった場合は、DmlExceptionを取得します。

古いレコードで更新しないようにする

for updateのロックが解除された後に別クライアントがレコードを更新する際、古レコードで更新してしまう可能性があるので注意する必要があります。

for updateでロックされているレコードを別クライアントが更新しようとした場合、updateコールが出てからすぐにロック解除されれば、別クライアントがレコードをロックし更新操作が成功します。

ただしこの場合、別クライアントが古い情報のレコードコピーを取得していると、古い情報でレコード更新してしまう可能性があります。

これを回避するためには、他のクライアントがレコードをロックした後、SELECTステートメントを使用してデータベースのレコードの最新のコピーを取得する必要があります。

コールアウト実行時の注意点

Salesforceのfor updateを使用してsObjectレコードをロックした後、コールアウトを実行するとロックが自動的に解除されます。

SalesforceのApexコードでfor updateを使用してロックを行った際、コールアウト実行時に自動的にロックが解除されます。for updateが以前に実行された可能性のあるコンテキストでコールアウトを実行する際は注意してください。

forループ内でfor updateを使用する方法


Salesforceのfor updateキーワードは、SOQLのforループ内で使用することができます。

以下のサンプルコードは、SOAP APIのquery( )メソッドと、queryMore( )メソッドのコールに対応しています。commitステートメントはありません。

Apexトリガが正常完了すると、自動的にデータベースの更新が行われ、Apexトリガが正常完了しないと、データベースの変更はロールバックされます。

for updateのデッドロックを回避する


Salesforceのup dateでsObjectレコードをロックする場合、デッドロックを回避する必要があります。

デッドロックとは、2つのプロセスにおいてお互いがロック解除待ち状態となり、どちらも処理が進まない状態のことをいいます。

Apexコードはデッドロックが発生する可能性があるので、デッドロックを回避するためApexランタイムエンジンでは以下の処理を行います。

1. sObjectの親レコードをロックした後に子レコードをロックします。
2. 複数の同じ型のレコードを編集している場合はIDの順番にsObjectレコードをロックします。

Apexコードで開発する場合、デッドロックが引き起らないように開発者は慎重にプログラミングをする必要があります。ロックを行う個所において、同じ順番でレコードにアクセスすることでデッドロックを回避することができます。

Salesforceのfor updateを使いこなそう!


今回は、Salesforceのfor updateについて説明しました。

for updateを使用すれば、複数のクライアントが同じレコードを更新する場合、更新前にロックをかけて、他のクライアントが更新できないようにすることが可能です。更新が終わればロックを解除することで、他のクライアントが更新可能となります。

ぜひこの機会に理解しておきましょう。


Salesforceでのキャリアアップをお考えの方は、現在募集中の求人情報をご覧ください。

また、直接のエントリーも受け付けております。

エントリー(応募フォーム)
FEnetからご応募→夢テクノロジー入社でお祝い金最大120万円プレゼント

Search

Popular

Categories

Tags