You need to sign in to do that
Don't have an account?
Mark Moore 7
How to Eliminate @HttpPost Race Condition
This is a cross-post to salesforce.stackexchange.com.
I have a custom API that accepts incoming @HttpPost requests from third parties. The POST request inserts a new complex custom object that may contain one or more Contact records.
There is a race condition between the [SELECT Id FROM Contact WHERE LastName = :newContact.LastName].size() > 0 test and the insert newContact.
This seems like a pretty serious limitation. So, I'm hoping others have found a solution. I have read through the Apex reference, and I can't find anything to eliminate this race.
More Info:
This has turned out to be a pretty serious issue. I'm surprised no one else has run into this. I have now modified the code to try 5 times to either insert the new record, or find the existing record. If I try to upload records with 245 roughly simultaneous POSTs, 47 fail (fail to create or find the existing crew member Contact record).
Here is the modified code:
What am I missing?
I have a custom API that accepts incoming @HttpPost requests from third parties. The POST request inserts a new complex custom object that may contain one or more Contact records.
There is a race condition between the [SELECT Id FROM Contact WHERE LastName = :newContact.LastName].size() > 0 test and the insert newContact.
This seems like a pretty serious limitation. So, I'm hoping others have found a solution. I have read through the Apex reference, and I can't find anything to eliminate this race.
More Info:
This has turned out to be a pretty serious issue. I'm surprised no one else has run into this. I have now modified the code to try 5 times to either insert the new record, or find the existing record. If I try to upload records with 245 roughly simultaneous POSTs, 47 fail (fail to create or find the existing crew member Contact record).
Here is the modified code:
private static Id StoreNewCrewMember(Contact newCrew) { if (newCrew == null) { return null; } if (String.isBlank(newCrew.EMSID__c)) { return null; } Integer i = 0; for (i = 0; i < 5; ++i) { Contact[] existingCrew = [SELECT Id FROM Contact WHERE EMSID__c = :newCrew.EMSID__c AND MailingState = :newCrew.MailingState ]; if (existingCrew.size() > 0) { return existingCrew[0].Id; } try { insert newCrew; return newCrew.Id; } catch (DmlException ex) { } } throw new DmlException('Failed '+i+' attempts to create Crew record'); }
What am I missing?
If developer.salesforce.com/forums is this dead/useless, why not just merge the whole forum over to salesforce.stackechange and point developers there? :-?
This is a real issue, and I'm certain this affects almost anyone exposing a REST API that allows inserting new records.
I'll comeback and update with any solution I find, but WOW this is a lame support forum.
We paid to have Premium tech support (just at T3 (tier 3) now). Here is a link to a "success" for a similar race condition that has a work around of "just try again":
https://success.salesforce.com/issues_view?id=a1p300000008YBEAA2
"Just try again" doesn't work for me because the crew contact collision is nested inside a parent structure. I don't have the ability to roll back the inserts that had succeeded before the crew collision eventually fails. I am actually shocked by how lame a work around that is.
I'm hoping T3 or someone in the Salesforce developer community knows how to implement a manual atomic test-and-set (SELECT-and-insert).
At least now I know I'm not the only guy with this issue. <sigh>