One of the challenges faced by any database system, including Salesforce, has to do with concurrency - what happens when more than one person attempts to modify a record at the same time? Obviously that can lead to trouble. To prevent this from occurring, Salesforce uses record locking - if two people are looking at the same record, and one modifies the record, the other can't modify that record until the first one's modifications are fully committed. In some cases Salesforce even ensures that the second person has reloaded the record so they are looking at the most up to date version. That's why sometimes when trying to save a record you'll get an error message that the record can't be saved because it has been modified by someone else.
Salesforce doesn't always lock a single record. To preserve data integrity it will sometimes lock related records. For example: in a parent-child relationship, if you modify a child record, the parent will be locked as well. Common examples that apply when working with response management are contact records, that lock the related account, and CampiagnMember records, that lock the related campaign, and lead or contact.
On a busy system, these related record lock can cause issues updating records. For example: let's say you are using a marketing automation system that is associating a large number of leads to a single campaign by creating CampaignMember records one at a time. This isn't good practice - ideally the marketing automation system would perform an operation like that in bulk, but some organizations have things set up to insert them individually. Each of those operations will lock the campaign - and if you have them coming in at a rapid pace, they can keep that campaign locked. So you'll start seeing lock errors in the marketing automation system and possibly in response management and other integrations.
How Response Management Handles Lock errors
Lock errors are almost inevitable on any busy system. Because you have real users performing real operations, the odds are that sooner or later two users will be trying to access the same record at the same time. The more integrations you have, the worse the situation can get. Having code and declarative functionality that works with related records also increases the odds of lock errors occurring - because they increase the number of records and relationships that may be locked during the operation.
Response management is designed to be very tolerant of lock errors in a number of ways:
- Most asynchronous commands check for lock errors. If one occurs, they will retry a set number of times.
- Custom funnels operations will retry for up to an hour if lock errors occur.
- Asynchronous reactivation will retry if lock errors occur.
- For general response management, if a lock error occurs when trying to update a Lead, Contact, or CampaignMember, the information will be stored in a deferred update record and will be reprocessed.
Lock errors that can't be recovered from are stored in the event log to be handled manually. Deferred update items and Asynchronous Request records with errors are also indicators of issues such as Lock errors and should be reviewed and handled manually.
What Can You Do About Lock Errors?
There are things you can do to minimize locking errors on systems
Lock errors occur when different users (threads) access locked records at the same time. This means there are two components to a lock error - parallelism - two users or threads operating at the same time, and commonality - accessing the same object.
Say you are using the bulk API to insert CampaignMembers. By default the bulk API will attempt parallel operation - two or more threads at once. If each batch is inserting records for a different campaign, all should be well. But if they are inserting records into the same campaign, you have a good chance of a lock.
Say you have a marketing automation that wants to associate 100 leads to the same campaign. If it does them in a single bulk operation, all will be well - you just have one thread. But if it tries to do so in 100 different operations, that will be 100 threads attempting to lock the same campaign - which almost guarantees lock errors.
Among the things you can do to minimize lock errors are therefore:
- If you are performing a bulk operation (data upload, for example) that involves a single record or related record, don't do them in parallel. Use serial mode if you are using the bulk API. Use smaller batches. Avoid large numbers of individual operations.
- Avoid data skew. For example: if you have a very large number of contacts on an account, each edit to any of those contacts will lock the account, increasing the odds of lock errors for all of those contacts and the account.
If you see excessive numbers of lock errors, in most cases it will take more in-depth diagnostics and possibly use of debug logs to determine where the problem lies.
There are things you can do to respond to locking errors on systems
As mentioned earlier, some lock errors are inevitable on any busy system. So it is important to be prepared to handle them both from an operational and development perspective.
With regards to Response Management:
- Most lock errors will be retried automatically. However, watch the event logs and deferred update item list for the appearance of unhandled lock errors. In most cases you can reprocess them manually.
- Watch for async records marked as errors with lock errors that do not get reprocessed. If you see lock errors persisting that suggests something significant is going on in the system that should be addressed. Note that async records may take some time to process, depending on the system.