How to Fix the UNABLE_TO_LOCK_ROW Error in Salesforce?

How to Fix the UNABLE_TO_LOCK_ROW Error in Salesforce?

On October 8, 2025, Posted by , In Admin Tutorial,Apex Triggers, By , , With Comments Off on How to Fix the UNABLE_TO_LOCK_ROW Error in Salesforce?
 UNABLE_TO_LOCK_ROW

When working with Apex triggers in Salesforce, you might encounter the error message “UNABLE_TO_LOCK_ROW” during DML operations like update or insert. This error usually occurs when multiple transactions try to access and modify the same record simultaneously, and Salesforce’s row-level security and record-locking mechanisms prevent them from doing so at the same time. Let’s understand this issue in detail and how it can be resolved.

The Salesforce platform enforces Row-Level Security, which ensures that all record-sharing and visibility rules defined by administrators are maintained. When a record is being updated, Salesforce automatically locks that record and any related parent records to maintain data integrity. The lock ensures that no other transaction can modify the same record until the current one completes successfully.

Consider a situation where sales representatives are adding new contacts to an account. When the Save button is clicked, the system automatically locks the parent Account record before inserting the Contact record. Once the trigger and other save operations complete, the database releases the lock. However, if multiple users try to add contacts to the same account simultaneously, the second user’s transaction will wait for the first to finish. If it takes too long or conflicts occur, Salesforce throws the UNABLE_TO_LOCK_ROW error.

This issue becomes more severe when data skew occurs — that is, when too many child records are related to a single parent record or when too many records share the same owner in a private sharing model. In such cases, the system has to perform heavy sharing calculations to maintain visibility and implicit sharing (for example, when a Contact provides read access to its parent Account). These calculations may increase the locking time and cause contention between concurrent transactions.

A similar problem can occur in master-detail relationships, where the parent record is automatically locked when any of its child records are inserted, updated, or deleted. For example, in your case, the quotepotential trigger updates the related Quote__c record whenever Quote_Line_Item__c records are inserted or updated. If multiple users or processes update quote line items under the same quote at the same time, Salesforce may lock that quote record, resulting in the “UNABLE_TO_LOCK_ROW” error.

Here is the problematic trigger code that can lead to locking issues:

trigger quotepotential on Quote_Line_Item__c (after insert, after update) {
    Set<Id> quoteIds = new Set<Id>();
    List<Quote__c> quotes = new List<Quote__c>();
    for (Quote_Line_Item__c record : Trigger.new) {
        if (record.Quote1__c != null) {
            quoteIds.add(record.Quote1__c);
        }
    }
    for (AggregateResult ar : [
        SELECT Quote1__c, SUM(Max_Batch__c) sumMax
        FROM Quote_Line_Item__c
        WHERE Quote1__c = :quoteIds
        GROUP BY Quote1__c
    ]) {
        quotes.add(new Quote__c(
            Id = (Id) ar.get('Quote1__c'),
            Potential__c = (Decimal) ar.get('sumMax')
        ));
    }
    if (!quotes.isEmpty()) {
        update quotes;
    }
}

Code Explanation:

This trigger runs after a Quote Line Item is inserted or updated. It first collects all the related Quote record IDs into a Set to avoid duplicates. Then, it runs an aggregate query to calculate the sum of Max_Batch__c for each Quote. The loop then creates new Quote records with updated Potential__c values using the aggregated results. Finally, it updates the list of quotes with new totals. The potential issue is that when multiple users update line items for the same Quote, concurrent updates try to lock the same Quote record, causing the UNABLE_TO_LOCK_ROW error.
To handle such situations, you can use the FOR UPDATE keyword in SOQL queries. This keyword ensures that Salesforce locks the records being queried at the time of retrieval, preventing other transactions from modifying them until your transaction completes. For example:

Account[] accts = [SELECT Id FROM Account LIMIT 2 FOR UPDATE];

Code Explanation:

This SOQL query selects two Account records and applies a FOR UPDATE lock on them. It means these records are now locked for other transactions trying to modify them until the current transaction finishes. This approach ensures your Apex code gets exclusive access to the records during processing, helping to avoid race conditions and record lock errors. However, you should use it carefully, as excessive use of FOR UPDATE can cause performance bottlenecks if too many records are locked at once.

In addition to using FOR UPDATE, you should also optimize your data model to prevent record and ownership skews. Try not to have more than 10,000 child records related to a single parent record. Distribute ownership so that no single user owns too many records, especially in a private sharing model. This approach reduces the number of sharing recalculations required and minimizes the chances of locking errors.

If your organization frequently faces such locking issues even after optimization, you can contact Salesforce Support to enable Granular Locking, a feature that allows the platform to lock individual child records instead of locking the entire parent hierarchy. This setting improves concurrency and reduces locking conflicts in large data environments.

For more in-depth details and examples, you can refer to Salesforce’s official resources:

  • Avoid Getting Lock Errors in Salesforce
  • Reducing Lock Contention by Avoiding Account Data Skews

In summary, the UNABLE_TO_LOCK_ROW error is not a bug but a result of Salesforce’s security and data integrity mechanisms. Understanding record locking, data skew, and sharing recalculations helps you design better data models and trigger logic. By applying solutions like the FOR UPDATE keyword, avoiding data skew, and using granular locking, you can prevent such locking issues and ensure smooth concurrent updates in your Salesforce org.

Kick Start Your Journey with Salesforce Learning

Our Salesforce course offers a thorough and engaging learning experience, providing you with the essential skills needed to succeed in the CRM field. The program covers key areas like Salesforce Admin, Developer, and AI, combining detailed theoretical education with hands-on practical experience. Through live projects and assignments, you’ll gain the expertise to solve complex business challenges using Salesforce solutions. Our expert instructors are dedicated to helping you develop both technical skills and industry insights.

In addition to technical training, our Salesforce training in Singapore offers personalized mentorship, guidance on exam preparation, and interview readiness to help you stand out in a competitive job market. You’ll have access to comprehensive study resources, real-world project exposure, and continuous support throughout your learning journey. By the end of the course, you’ll be well-prepared for certification exams and equipped with the practical skills and problem-solving capabilities that employers value. Start your Salesforce career with us and unlock a range of exciting career opportunities!

Comments are closed.