2021/08/12

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

 
  

Salesforceのfor updateとは?

Salesforceのfor updateとは、sObjectレコードをロックして競合の条件や安全面を確保するするためのものです。 for updateを使用してsObjectをロックすると、他のすべてのユーザーやクライアントは、Salesforceユーザーインターフェースを使って更新を行うことができなくなります。 一方、レコードをロックしているクライアント側は、レコードにロジックを実行して更新を行うことができます。 ロック中は、ロックしているレコードが別のクライアントによって変更されることはありません。ロックしているクライアントのトランザクションが完了すると、レコードのロックが解除されます。

for updateの使い方

Salesforceのfor updateは、インラインSOQLステートメントの後に埋め込みます。 ApexコードでsObjectレコードをロックするには、インラインSOQLステートメントの後にfor updateキーワードを埋め込む必要があります。例えば、次のサンプルコードでは、2つの取引先を照会し、返された取引先レコードをロックしています。
Account [] accts = [SELECT Id FROM Account LIMIT 2 FOR UPDATE];
ロックを使用する場合は、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 (Account[] accts : [SELECT Id FROM Account
                        FOR UPDATE]) {
    // Your code
}

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

Salesforceのup dateでsObjectレコードをロックする場合、デッドロックを回避する必要があります。 デッドロックとは、2つのプロセスにおいてお互いがロック解除待ち状態となり、どちらも処理が進まない状態のことをいいます。 Apexコードはデッドロックが発生する可能性があるので、デッドロックを回避するためApexランタイムエンジンでは以下の処理を行います。 1. sObjectの親レコードをロックした後に子レコードをロックします。 2. 複数の同じ型のレコードを編集している場合はIDの順番にsObjectレコードをロックします。 Apexコードで開発する場合、デッドロックが引き起らないように開発者は慎重にプログラミングをする必要があります。ロックを行う個所において、同じ順番でレコードにアクセスすることでデッドロックを回避することができます。

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

今回は、Salesforceのfor updateについて説明しました。 for updateを使用すれば、複数のクライアントが同じレコードを更新する場合、更新前にロックをかけて、他のクライアントが更新できないようにすることが可能です。更新が終わればロックを解除することで、他のクライアントが更新可能となります。 ぜひこの機会に理解しておきましょう。]]>

ITエンジニアへのキャリアチェンジならキャリアチェンジアカデミー

この記事の監修者・著者

株式会社オープンアップITエンジニア
株式会社オープンアップITエンジニア
未経験からITエンジニアへのキャリアチェンジを支援するサイト「キャリアチェンジアカデミー」を運営。これまで4500人以上のITエンジニアを未経験から育成・排出してきました。
・AWS、salesforce、LPICの合計認定資格取得件数:2100以上(2023年6月時点)
・AWS Japan Certification Award 2020 ライジングスター of the Year 受賞

おすすめの動画

  • 【未経験からIT業界へ転職するなら】相談窓口とスキルの獲得はここで解決!IT転職が一気に有利に!【キャリアチェンジアカデミー】

  • 【費用一切不要】未経験からIT業界へ転職するならまずはここへ相談!【キャリアチェンジアカデミー】

  • 【何のエンジニアになれるのか?】未経験からITエンジニアを目指すとこんな道がある【キャリアチェンジアカデミー】