You deploy a new automation, run a data migration, or execute a Batch Apex job, and everything appears to work normally. Then suddenly Salesforce throws an error similar to this:
UNABLE_TO_LOCK_ROW
At first glance, the message looks confusing because it doesn’t clearly explain what went wrong. Unlike validation rule errors or field-level security issues, the UNABLE_TO_LOCK_ROW Error in Salesforce is related to record locking. The error usually occurs when multiple users, automation processes, integrations, or Apex transactions attempt to update the same record simultaneously.
This issue is extremely common in organizations that process large amounts of data through Salesforce Data Loader Tutorial for Beginners, Batch Apex in Salesforce: Complete Guide with Real Examples, or external integrations. Although the error may appear randomly, there is always an underlying locking conflict that Salesforce is trying to prevent.
This post covers what causes the error, how to find it, and the exact fixes. what causes the UNABLE_TO_LOCK_ROW Error in Salesforce, how to identify the root cause, and the most effective ways to fix it using real-world examples and Salesforce best practices.
If you regularly work with Batch Apex in Salesforce: Complete Guide with Real Examples, Salesforce Data Loader Tutorial for Beginners, or Salesforce Integration Best Practices: Complete Guide for Scalable Systemss, understanding how Salesforce record locking works can help you troubleshoot this error much faster..
Understanding the UNABLE_TO_LOCK_ROW Error
The UNABLE_TO_LOCK_ROW Error occurs when Salesforce cannot obtain an exclusive lock on a record because another transaction is already using it.
Whenever Salesforce updates a record, it temporarily locks that record to maintain data consistency. This prevents multiple users or processes from overwriting each other’s changes at the same time.
Imagine User A updates an Opportunity record while, at the same moment, a Flow attempts to update the same Opportunity. Salesforce must decide which transaction gets access first. To prevent data corruption, Salesforce locks the record during processing.
If another transaction tries to access the same record before the lock is released, Salesforce throws:
UNABLE_TO_LOCK_ROW
This behavior is completely normal and exists to protect data integrity.
Organizations using Salesforce Integration Best Practices: Complete Guide for Scalable Systems, Salesforce REST API Tutorial for Beginners with Real Integration Examples, and Web to Lead Form in Salesforce: Complete Step-by-Step Guide (2026) often encounter this error when multiple systems interact with Salesforce simultaneously.
Why Does UNABLE_TO_LOCK_ROW Happen?
The UNABLE_TO_LOCK_ROW error occurs when two or more Salesforce transactions attempt to update the same record at nearly the same time. To maintain data consistency, Salesforce temporarily locks a record while it is being updated. During that period, no other transaction can modify the same record until the first operation completes.
This situation is common in organizations that rely heavily on automation. A Record-Triggered Flow may update an Account while a Batch Apex job is processing related Contacts, or an external integration may send updates at the same moment a user edits the record in Salesforce. Since all of these operations compete for the same database record, Salesforce blocks one of them and throws the UNABLE_TO_LOCK_ROW exception.
For example, imagine two transactions trying to update the same Account record:
// Transaction A
Account acc = [SELECT Id, Name FROM Account WHERE Id = :accountId];
acc.Name = 'Updated by Flow';
update acc;
// Transaction B
Account acc2 = [SELECT Id, Name FROM Account WHERE Id = :accountId];
acc2.Name = 'Updated by Batch Job';
update acc2;
If Transaction B attempts to save changes before Transaction A releases the lock, Salesforce prevents the update and generates the UNABLE_TO_LOCK_ROW error. The issue is not caused by bad data but by concurrent access to the same record.
How Salesforce Record Locking Works
Many Salesforce professionals encounter the error without understanding what is actually happening behind the scenes.
The process looks like this:
User or Automation Starts Transaction
↓
Salesforce Locks Record
↓
Record Is Updated
↓
Changes Are Saved
↓
Lock Is Released
Now imagine another transaction arrives before the lock is released:
Transaction A
↓
Locks Opportunity
↓
Still Processing
↓
Transaction B Attempts Update
↓
Record Already Locked
↓
UNABLE_TO_LOCK_ROW Error
This situation becomes more common as automation complexity increases.
Diagram: Record Locking Process
User A Updates Record
↓
Record Locked
↓
Flow Executes
↓
Trigger Executes
↓
Database Update
↓
Lock Released
Meanwhile...
User B Updates Same Record
↓
Unable To Obtain Lock
↓
UNABLE_TO_LOCK_ROW
Common Causes of UNABLE_TO_LOCK_ROW Error
Understanding the root causes is essential because the solution depends on the source of the locking conflict.
Batch Apex Processing Related Records
One of the most common causes occurs during Batch Apex execution.
Imagine a batch job processes thousands of Contacts. Multiple batch executions may attempt to update the same parent Account simultaneously.
When this happens, Salesforce prevents concurrent updates and throws the locking exception.
Developers working with Batch Apex in Salesforce: Complete Guide with Real Examples should always consider parent-child record relationships when designing large-scale processing jobs.
Multiple Flows Updating the Same Record
Modern Salesforce organizations often rely heavily on Flow.
For example:
- Record Triggered Flow
- Scheduled Flow
- Auto-Launched Flow
If multiple flows attempt to update the same record simultaneously, locking conflicts can occur.
This is especially common when organizations build automation without a centralized design strategy.
If you use Flow extensively, reviewing Salesforce Admin Certification Complete Guide for Beginners (2026) can help identify automation overlaps.
Data Loader Imports
Large imports frequently expose locking issues.
For example:
- Opportunity import
- Contact migration
- Lead conversion project
During imports, Salesforce processes multiple records simultaneously.
If those records share the same parent object, locking conflicts become much more likely.
Organizations using Salesforce Data Loader Tutorial for Beginners often encounter this issue during data migration projects.
Apex Triggers
Triggers can indirectly create locking conflicts.
For example:
Opportunity Trigger
↓
Updates Account
↓
Account Trigger Fires
↓
Additional Updates
As automation layers increase, the chance of locking conflicts also increases.
Developers should review Apex Trigger Tutorial for Beginners in Salesforce to understand transaction behavior.
Real-World Business Scenario
A global manufacturing company integrated Salesforce with its ERP system.
Every time an order was updated in the ERP platform:
- Salesforce Opportunity updated
- Salesforce Account updated
- Custom Order object updated
At the same time:
- Sales representatives updated Opportunities manually
- Scheduled Flows executed every hour
- Queueable Apex jobs synchronized inventory information
Initially, everything worked correctly. However, as transaction volume increased, users began receiving UNABLE_TO_LOCK_ROW errors.
After reviewing debug logs, the development team discovered multiple automation processes updating the same Account records simultaneously.
The solution involved restructuring automation, reducing concurrent updates, and implementing asynchronous processing where appropriate.
As a result:
- Error rate dropped significantly
- Data synchronization improved
- User experience became more reliable
This example demonstrates why understanding transaction behavior is just as important as writing efficient Apex code.
How to Identify the Root Cause
Finding the source of the locking conflict is often more challenging than fixing it.
Start by enabling Debug Logs.
Navigate to:
Setup
↓
Debug Logs
Reproduce the issue and review the transaction details.
Search for:
UNABLE_TO_LOCK_ROW
Pay close attention to:
- Trigger execution
- Flow execution
- Integration requests
- Batch jobs
- Queueable jobs
Developers using Salesforce Developer Console Tutorial for Beginners can also analyze execution logs to determine which transaction attempted to acquire the lock.
Solution 1 : Optimize Batch Apex Processing
Batch Apex is one of the most common sources of record locking issues. While Batch Apex is designed to process large volumes of records efficiently, it can create problems when multiple batch executions attempt to update records that share the same parent object.
For example, imagine a batch job processing thousands of Contacts. If hundreds of those Contacts belong to the same Account, Salesforce may attempt to update the Account repeatedly across multiple batch executions. As transaction overlap increases, record locking conflicts become more likely.
To reduce this risk:
- Process smaller batch sizes
- Avoid unnecessary parent record updates
- Group related records together
- Minimize cross-object updates
Developers working with Batch Apex in Salesforce: Complete Guide with Real Examples, and Salesforce Governor Limits with Real Examples and Best Practices should always evaluate how parent-child relationships impact transaction behavior.
Solution 2 : Review Salesforce Flow Automation
Many organizations have moved significant business logic into Salesforce Flow. While Flow is extremely powerful, poorly designed automation can create unexpected locking conflicts.
A common scenario occurs when:
Record Triggered Flow
↓
Updates Parent Account
↓
Another Flow Executes
↓
Updates Same Account
↓
Record Lock Conflict
As automation grows, these interactions become difficult to identify without proper documentation.
When troubleshooting:
- Review all active Flows
- Check entry criteria
- Identify overlapping updates
- Reduce duplicate automation
Administrators who understand Salesforce Admin Certification Complete Guide for Beginners (2026), and Salesforce Configuration vs Customization: Key Differences and When to Use Each typically identify these issues much faster.
Diagram: Flow Locking Conflict
Flow A
↓
Updates Account
↓
Record Locked
Meanwhile
Flow B
↓
Attempts Account Update
↓
UNABLE_TO_LOCK_ROW
Solution 3: Improve Integration Design
Salesforce integrations frequently contribute to locking problems because external systems often process records in parallel.
For example:
ERP System
↓
Updates Account
Marketing Platform
↓
Updates Account
Salesforce User
↓
Updates Account
Three independent systems may attempt to update the same record at nearly the same time.
Organizations implementing Salesforce Integration Best Practices: Complete Guide for Scalable Systems Types of Salesforce Integrations: Complete Guide for Beginners, and Salesforce REST API Tutorial for Beginners with Real Integration Examples should carefully evaluate transaction timing and synchronization patterns.
In many cases, introducing retry logic significantly reduces locking failures.
Solution 4: Use FOR UPDATE Carefully
Salesforce provides the FOR UPDATE clause for situations where explicit record locking is required.
Example:
SELECT Id, Name
FROM Account
WHERE Id = :accountId
FOR UPDATE
This approach allows Salesforce to lock the record intentionally before processing.
However, developers should use this feature carefully because excessive locking can increase contention and negatively affect performance.
Understanding when to use FOR UPDATE is an advanced topic and should only be considered after other optimization techniques have been evaluated.
Common Errors and Solutions
| Error Scenario | Cause | Solution |
|---|---|---|
| Batch Apex failure | Parent record locking | Reduce batch size |
| Data Loader import failure | Simultaneous updates | Import during low activity periods |
| Integration conflict | Multiple systems updating records | Implement retry mechanism |
| Flow automation issue | Multiple Flows updating same record | Consolidate automation |
| Trigger conflict | Cross-object updates | Review trigger design |
| Queueable Apex failure | Concurrent processing | Sequence asynchronous jobs |
| Parent-child lock issue | Shared parent updates | Redesign transaction flow |
Real Production Example
A healthcare organization imported more than 250,000 Contact records using Data Loader. During the import, each Contact update triggered automation that updated the related Account record.
Since thousands of Contacts belonged to the same Accounts, Salesforce repeatedly attempted to update identical parent records. As a result, users experienced frequent UNABLE_TO_LOCK_ROW errors and the migration process slowed significantly.
The development team resolved the issue by:
- Reducing Data Loader batch sizes
- Removing unnecessary Account updates
- Moving some processing into Queueable Apex
- Optimizing trigger execution
After deployment, the import completed successfully with minimal locking conflicts.
This scenario highlights why understanding Salesforce Data Loader Tutorial for Beginners, Salesforce Admin Certification Complete Guide for Beginners (2026), and Queueable Apex in Salesforce for Beginners: Complete Async Processing Guide is critical when working with large datasets.
Best Practices to Prevent UNABLE_TO_LOCK_ROW Errors
Preventing the error is usually easier than fixing it after deployment.
Follow these recommendations:
Minimize Parent Record Updates
Updating parent records repeatedly is one of the leading causes of locking conflicts.
Review Automation Regularly
Organizations often accumulate Flows, Apex Triggers, and integrations over time. Regular reviews help identify overlapping processes.
Use Smaller Batch Sizes
Smaller transactions reduce the probability of concurrent updates.
Avoid Unnecessary Cross-Object Updates
Only update related records when absolutely necessary.
Design for High Data Volumes
Always assume future growth when building Salesforce solutions.
Developers familiar with Salesforce Developer Console Tutorial for Beginners and Apex Trigger Tutorial for Beginners in Salesforce generally create more scalable applications.
Mistakes to Avoid
Running Large Imports During Business Hours
High user activity combined with bulk imports significantly increases locking conflicts.
Ignoring Existing Automation
Developers often focus only on new automation and overlook existing Flows and Triggers.
Processing Related Records Simultaneously
When multiple records share the same parent object, transaction design becomes extremely important.
Assuming the Error Is Random
The error always has a root cause. Proper log analysis will eventually identify the source.
Performance Considerations
Although record locking primarily affects data consistency, it also impacts performance.
Repeated transaction failures can:
- Increase processing time
- Delay integrations
- Slow batch jobs
- Reduce user productivity
Optimizing transaction design improves both performance and reliability.
Security Considerations
Record locking itself is not a security feature, but security architecture can influence transaction behavior.
Always:
- Respect CRUD permissions
- Enforce Field-Level Security
- Validate automation ownership
- Avoid excessive system-level updates
Secure automation tends to be easier to troubleshoot and maintain.
Frequently Asked Questions (FAQs)
What does UNABLE_TO_LOCK_ROW mean in Salesforce?
This error occurs when Salesforce cannot obtain a lock on a record because another user, Flow, Apex transaction, or integration is already updating it.
Can Salesforce Flow cause UNABLE_TO_LOCK_ROW?
Yes. Multiple Flows updating the same record or parent record can create locking conflicts.
Can Batch Apex trigger this error?
Yes. Batch Apex often processes records in parallel, which may result in multiple transactions attempting to update the same parent record.
How do I identify the source of the error?
Enable Debug Logs and search for UNABLE_TO_LOCK_ROW. The logs usually identify the Trigger, Flow, Apex Class, or integration involved.
Can Data Loader cause this issue?
Yes. Large imports frequently expose record locking problems, especially when many records share the same parent object.
Does reducing batch size help?
In many cases, yes. Smaller batches reduce concurrent updates and lower the risk of locking conflicts.
Can integrations cause record locking?
Absolutely. Multiple external systems updating the same records simultaneously is a common cause.
What is the best way to prevent this error?
Reduce simultaneous updates, optimize automation, review Flows and Triggers regularly, and avoid unnecessary parent record updates.
Conclusion
The UNABLE_TO_LOCK_ROW Error in Salesforce is a common record-locking issue that occurs when multiple transactions attempt to update the same record simultaneously. Although the error often appears during Batch Apex jobs, Data Loader imports, integrations, or Salesforce Flow automation, the root cause is usually overlapping updates on related records.
The most effective solution is to identify the process creating the conflict and redesign the transaction flow to reduce concurrent updates. By optimizing Apex code, reviewing automation, using appropriate batch sizes, and understanding Salesforce record locking behavior, you can significantly reduce these errors and build more scalable Salesforce applications.
If you frequently work with large data volumes, consider strengthening your understanding of Batch Apex in Salesforce: Complete Guide with Real Examples,Queueable Apex in Salesforce for Beginners: Complete Async Processing Guide and Salesforce REST API Tutorial for Beginners with Real Integration Examples, as these topics are closely related to record locking and transaction management.