When using the Salesforce API and creating an account using this endpoint
POST https://<mycompany>.my.salesforce.com/services/data/v51.0/sobjects/Account/
we once in a while fails with a 400 with this stacktrace:
[{"message":"rh2.PS_Account: execution of AfterInsert
caused by: System.DmlException: Upsert failed. First exception on row 0 with id <ID_REMOVED>; first error: UNABLE_TO_LOCK_ROW, unable to obtain exclusive access to this record or 1 records: <ID_REMOVED>: []
Class.rh2.PS_Run_Utility.turnOffValidationRules: line 212, column 1
Class.rh2.PS_Parent_Record_WrapperClass.updateParents: line 206, column 1
Class.rh2.PS_Parent_Record_WrapperClass.updateParentRecords: line 154, column 1
Class.rh2.PS_Rollup_Helper.addAndThenClearRollupContextParentFields: line 614, column 1
Class.rh2.PS_Rollup_Helper.performSync: line 524, column 1
Class.rh2.ParentUtil.performTriggerRollups: line 213, column 1
Trigger.rh2.PS_Account: line 7, column 1","errorCode":"CANNOT_INSERT_UPDATE_ACTIVATE_ENTITY","fields":[]}]
Based on the stacktrace it seems that something is having a lock in a database. When we get the 400 back, we do a retry. I can see that for one issue we, at the 6th retry, it seems to successfully have created the account. However, it seems that for every retry an account is created in Salesforce and hence we are ending up with duplicate accounts, so our id is linked to multiple accounts.
I'm trying to understand:
Why do we get a 400 back (so why is the parent locked?)
How should we perform our error handling for this scenario? I'm trying to figure out how we can be resillient enough and with a good retry logic without creating duplicates. Since it is a POST it is ok that the endpoint is not idempotent, however, since we do not get a accountId back in the response, I'm not sure have to make it idempotent on our side
Best regards Hans-Christian