Loading
Salesforce から送信されるメールは、承認済ドメインからのみとなります続きを読む

Race condition between Apex code and API Call

公開日: Apr 18, 2023
説明

In the following apex code, there's a possibility that the assert statement will fail if an API transaction executing in parallel was able to update the LastName. Select statement (with For update) will try to lock the record. But if record is already locked then it'll still select the record but wait for lock to be released (for 10 seconds). If record is released then second transaction will continue. 
 
List<Contact> myContactList = [SELECT Id, LastName FROM Contact where LastName = 'mylast' FOR UPDATE];
for (Contact c : myContactList){
    System.assertEquals('mylast', c.LastName.toLowerCase());
}
解決策
There's a possibility that the assert statement will fail if an API transaction executing in parallel was able to update the LastName. Select statement (with For update) will try to lock the record. But if record is already locked then it will still select the record but wait for lock to be released (for 10 seconds). If record is released then second transaction will continue. 

The locking process returns a fresh copy of the record from the database through the SELECT statement. But it doesn't really run SELECT statement again. It just does it "internally" to refresh the data of record which was already selected in the actual SOQL. So we have to check if the WHERE clause filter is still valid.

 
List<Contact> myContactList = [SELECT Id, LastName FROM Contact where LastName = 'mylast' FOR UPDATE];
for (Contact c : myContactList){
if (c.LastName == 'mylast')
    {System.assertEquals('mylast', c.LastName.toLowerCase());}
}


The behavior is also explained in this document .
ナレッジ記事番号

000387467

 
読み込み中
Salesforce Help | Article