Skip to main content
replaced http://salesforce.stackexchange.com/ with https://salesforce.stackexchange.com/
Source Link
Tweeted twitter.com/#!/StackSalesforce/status/413711771808309249
added more info about the real scenario
Source Link
Avidev9
  • 5.7k
  • 4
  • 38
  • 50

Update 1: Actual Production Scenario In production leads are generally created using web to lead form. We have a page with a button that assign records by pulling records from a queue and changes owner to the current user.

The query looks like

    Lead l = Database.query('SELECT Id,Name ,CreatedDate FROM Leads__c WHERE  Lead_Status__c =\'Open\' AND Owner.Name = 'My Queue' LIMIT 1 FOR UPDATE');
//some calculation 
l.OwnerId = UserInfo.getUserId();

My assumption was when the second user will try to access the same record(by using the same query) it will throw an error. But some how records are getting updated. There are some suspicious records in production where if I check the history

  • User 1 Changed Owner from My queue to User 1 [Same TimeStamp]
  • User 2 Changed Owner from User 1 to User 2 [Same TimeStamp]

The above observation makes me suspicious that the code actually waits. But again the docs :( . What makes it really hard is this situation is really hard to replicate and almost impossible.

Update 1: Actual Production Scenario In production leads are generally created using web to lead form. We have a page with a button that assign records by pulling records from a queue and changes owner to the current user.

The query looks like

    Lead l = Database.query('SELECT Id,Name ,CreatedDate FROM Leads__c WHERE  Lead_Status__c =\'Open\' AND Owner.Name = 'My Queue' LIMIT 1 FOR UPDATE');
//some calculation 
l.OwnerId = UserInfo.getUserId();

My assumption was when the second user will try to access the same record(by using the same query) it will throw an error. But some how records are getting updated. There are some suspicious records in production where if I check the history

  • User 1 Changed Owner from My queue to User 1 [Same TimeStamp]
  • User 2 Changed Owner from User 1 to User 2 [Same TimeStamp]

The above observation makes me suspicious that the code actually waits. But again the docs :( . What makes it really hard is this situation is really hard to replicate and almost impossible.

a bit of explanation
Source Link
Avidev9
  • 5.7k
  • 4
  • 38
  • 50

Well I was trying to Implement Record Locking apex but Salesforce Document doesn't seem to help much. Even tried searching stackexchange there was a old question but the answer form StackExchange and details from document seems to be conflicting.

According to Salesforce Doc whenever a second transaction tries to lock a record that is already locked it will throw an "QueryException" whereas from the Stackexchange it seems like the second thread will actually wait.

Q1: I am bit confused about what will happen ? Will it fail(throw exception) or will it wait for 4-5 seconds and then if it doesn't get access it will throw an exception ?

That was related to docs. In production we are facing a issue where second thread seems to get access to the record even though we have put a lock, second transaction seems to get access, may be after sometime but doesn't seems to throw any exception immediatelymay be after sometime but doesn't seems to throw any exception immediately. For example we have a method

public static void updateMyAccount(){
Account acc = [SELECT Id FROM Account WHERE isValid = TRUE AND Id='SOME ID' FOR UPDATE];
//some time consuming process...callouts etc here
 acc.isValid__c = false;
 update acc;

}

Scenario:(assuming the system waits)

  • Lets assume Thread 1 calls the above method and acquires a lock on the RECORD.
  • Now while Transaction 1 is processing the record another Thread Transaction 2 tries to access the record and waits for the lock to release
  • While the transaction 2 is waiting thread one changes "isValid__c" to false and the record no more matches the query condition.

Q2 : In the above case will the second thread get access to the record ? or the query will not return any record ?

Q3 : When does the lock gets released ? the Salesforce doc doesn't seems to provide much insight into it. does the lock get released after a DML ? or it waits for full transaction to complete ?

Well I was trying to Implement Record Locking apex but Salesforce Document doesn't seem to help much. Even tried searching stackexchange there was a old question but the answer form StackExchange and details from document seems to be conflicting.

According to Salesforce Doc whenever a second transaction tries to lock a record that is already locked it will throw an "QueryException" whereas from the Stackexchange it seems like the second thread will actually wait.

Q1: I am bit confused about what will happen ? Will it fail(throw exception) or will it wait for 4-5 seconds and then if it doesn't get access it will throw an exception ?

That was related to docs. In production we are facing a issue even though we have put a lock second transaction seems to get access, may be after sometime but doesn't seems to throw any exception immediately. For example we have a method

public static void updateMyAccount(){
Account acc = [SELECT Id FROM Account WHERE isValid = TRUE AND Id='SOME ID' FOR UPDATE];
//some time consuming process...callouts etc here
 acc.isValid__c = false;
 update acc;

}

Scenario:(assuming the system waits)

  • Lets assume Thread 1 calls the above method and acquires a lock on the RECORD.
  • Now while Transaction 1 is processing the record another Thread Transaction 2 tries to access the record and waits for the lock to release
  • While the transaction 2 is waiting thread one changes "isValid__c" to false and the record no more matches the query condition.

Q2 : In the above case will the second thread get access to the record ? or the query will not return any record ?

Q3 : When does the lock gets released ? the Salesforce doc doesn't seems to provide much insight into it. does the lock get released after a DML ? or it waits for full transaction to complete ?

Well I was trying to Implement Record Locking apex but Salesforce Document doesn't seem to help much. Even tried searching stackexchange there was a old question but the answer form StackExchange and details from document seems to be conflicting.

According to Salesforce Doc whenever a second transaction tries to lock a record that is already locked it will throw an "QueryException" whereas from the Stackexchange it seems like the second thread will actually wait.

Q1: I am bit confused about what will happen ? Will it fail(throw exception) or will it wait for 4-5 seconds and then if it doesn't get access it will throw an exception ?

In production we are facing a issue where second thread seems to get access to the record even though we have put a lock, second transaction seems to get access, may be after sometime but doesn't seems to throw any exception immediately. For example we have a method

public static void updateMyAccount(){
Account acc = [SELECT Id FROM Account WHERE isValid = TRUE AND Id='SOME ID' FOR UPDATE];
//some time consuming process...callouts etc here
 acc.isValid__c = false;
 update acc;

}

Scenario:(assuming the system waits)

  • Lets assume Thread 1 calls the above method and acquires a lock on the RECORD.
  • Now while Transaction 1 is processing the record another Thread Transaction 2 tries to access the record and waits for the lock to release
  • While the transaction 2 is waiting thread one changes "isValid__c" to false and the record no more matches the query condition.

Q2 : In the above case will the second thread get access to the record ? or the query will not return any record ?

Q3 : When does the lock gets released ? the Salesforce doc doesn't seems to provide much insight into it. does the lock get released after a DML ? or it waits for full transaction to complete ?

Source Link
Avidev9
  • 5.7k
  • 4
  • 38
  • 50
Loading