We are using the CreateSalesforceObject AMPscript function to create a new record in the Salesforce CampaignMember Object when an email is sent, by including the following code in an email:

set @campaignMemberId = CreateSalesforceObject('CampaignMember', 3, 'CampaignId', @campaignId, 'ContactId', @id,'Status','Sent')

When we run a test send, it works fine; the Campaign Member record is created successfully. However, when we deployed the email to a large number of subscribers, the email was cancelled.

We asked Marketing Cloud Support who cancelled this job (it wasn't us), and they informed us that their Operations Team intentionally cancelled the send. Why? Well apparently our AMPscript was generating the following exception error:

Call to create the salesforceobject CampaignMember failed! 
Error status code: UNABLE_TO_LOCK_ROW 
Error message: unable to obtain exclusive access to this record 

After our investigation, it appears that this is due to Salesforce Platform Record Locking and Concurrency, where certain Objects, including the CampaignMember object (which we are using), are locked while a record is upserted.

Here's a related knowledge article. The solutions offered in this article of 'reduce the batch size' or 'process the records in Serial mode instead of parallel' aren't really an option when sending emails to a large number of subscribers.

I find it hard believe that we're the only ones who have experienced this issue before. I note that core Salesforce objects, including Account, Case, Contact, Event and other objects all employ a high risk of lock contention (refer to cheat sheet).

If anyone can provide a solution to workaround this issue, I'd really appreciate it!

  • Hey Eliot - would executing the campaign via Journey Builder, and then use the standard create campaign member sf activity, be a viable workaround? Jun 12, 2017 at 9:36
  • alternatively - depending on the solution - would it be possible to deploy the data to a custom-object / staging table inside SF, and then use SF's own tools (Workflows, Process Builder or APEX) to create the campaign member records. APEX would allow you to catch-retry and do futures, would could enable a bit of control + it could add batch size if memory serves. Jun 12, 2017 at 9:37
  • If you just want to create a Campaign Member, then yes that should be a viable workaround. You could also perform this within Sales Cloud as you suggested. Jun 13, 2017 at 10:53
  • Did you manage to a viable workaround, If so, what did you end Up doing? :) Jun 13, 2017 at 11:10
  • 1
    The solution I came up with was to call the CreateSalesforceObject function after the email had been sent from a CloudPage Resource, recursively working through each record in a DE. A little clumsy, I know. Jun 14, 2017 at 2:44


You must log in to answer this question.

Browse other questions tagged .