Understanding Mixed DML Operations in Salesforce and How to Fix Them

 

Introduction

If you have ever encountered the dreaded System.DmlException: DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa) error in Salesforce, you’ve bumped into the Mixed DML Operation restriction. This error is common for developers and admins automating business processes with Apex, Flows, or Triggers. This blog explains what mixed DML is, why Salesforce enforces it, the error’s implications, and how to fix or work around it.


What is Mixed DML in Salesforce?

Salesforce has two types of objects:

  • Setup Objects: Configuration/meta-data objects (e.g., User, UserRole, Group, PermissionSetAssignment, etc.)
  • Non-Setup Objects (Business Objects): Standard or custom objects for business data (e.g., Account, Opportunity, Custom__c, etc.).

Mixed DML occurs when you try to perform DML operations on both setup and non-setup objects within the same transaction context.

Examples of Setup vs Non-Setup Objects

Setup ObjectsNon-Setup Objects
UserAccount
UserRoleOpportunity
PermissionSetAssignmentContact
GroupCustom__c

Why Does Salesforce Restrict Mixed DML?

Salesforce enforces this rule to protect the integrity of your configuration and business data. Setup objects affect your org's security and access configuration, so mixing their changes with business data in a single transaction could create security risks or data inconsistencies.


The Error Message

When you try to do mixed DML, you'll see an error like:

System.DmlException: DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object: Account

Common Scenarios

  • Apex Triggers: Updating a User record after inserting an Account in the same transaction.
  • Batch Apex: Processing Account records and updating related User records.
  • Flows/Process Builder: Flows that update both User and Account in the same transaction.

How to Fix Mixed DML Errors

1. Use System.runAs() in Test Methods (Test Context Only)

Salesforce allows you to separate DML contexts in test methods using System.runAs():

@isTest public static void testMixedDML() { User u = new User(...); // Setup object insert u; System.runAs(u) { Account a = new Account(Name='Test Account'); insert a; // now safe in test context } }

Note: This only works in test methods.


2. Use @future Methods or Queueable Apex

Offload the DML operation to an asynchronous context:

public static void updateUserAsync(Id userId) { update [SELECT Id, IsActive FROM User WHERE Id = :userId]; } @future public static void updateUserFuture(Id userId) { updateUserAsync(userId); }

How to Use:

  • Perform non-setup DML synchronously.
  • Call the future/queueable method to perform setup DML.

Example:

// Synchronous insert new Account(Name='Test Acc'); // Asynchronous updateUserFuture(userId);

3. Rearrange DML Operations

Sometimes, simply changing the order of DML operations fixes the issue. Perform all setup object DMLs first, then non-setup object DMLs (or vice versa), but not both in the same context.


4. Use Separate Transactions

  • Use screen flows or orchestrations to split the operations.
  • Use external integrations (like middleware) to separate the two operations.

Best Practices to Avoid Mixed DML

  • Never mix setup and non-setup DML in the same trigger or method.
  • Document your automation flows to track possible mixed DML risks.
  • Refactor triggers to separate DML on User/Permission objects from business object DML.
  • Use asynchronous processing for setup DML whenever possible.

Summary Table

SolutionSynchronousAsynchronousTest Context
Rearrangement
@future/Queueable
System.runAs

References


Conclusion

Mixed DML errors can be frustrating, but they’re there for a good reason. By understanding the difference between setup and non-setup objects and using the right workarounds (like asynchronous Apex or rearranging your logic), you can design robust automations that respect Salesforce’s security model.


Have you struggled with Mixed DML? Share your experiences and solutions in the comments!

0 Comments

Post a Comment

Post a Comment (0)

Previous Post Next Post