This is what the allOrNone
parameter in the 2-argument version of the dml methods provided by the Database
class is for (you can also set in with DmlOptions
, which would also be passed into a method from the Database
class).
allOrNone
defaults to true, meaning if any of the records fail the entire operation fails.
If set to false, Salesforce will automatically roll back the partial work that was done by your DML statement, remove the failed records, and retry. This can happen up to twice (first attempt fails -> second attempt fails -> third and final attempt) before Salesforce gives up and errors out anyway.
Using allOrNone = false
does exhibit some weird behavior which you need to plan for carefully:
- Static variables are not reset when Salesforce retries the operation (this will cause issues with nearly all recursion prevention mechanisms that we commonly see)
- allOrNone = false on an Insert will mean that the records that didn't fail will be assigned completely new Ids (and I think autonumber fields continue to increment too)
- Using this means you should add additional code to check the saveResult (to see what succeeded, what failed, and possibly log/notify someone about the errors)
- If I remember correctly, this automatic retry mechanism only works for records which fail system or user-defined validation rules, or for records where you
.addError()
. Exceptions (null pointer exception, divide by 0, accessing an invalid index in a list, etc...) in general will override the automatic retry mechanism and continue to bubble up your call stack until handled