All About “MIXED_DML_OPERATION” error (Setup and Non-setup Object)

Introduction
Salesforce developers often encounter Mixed DML exceptions, but there’s confusion around when they occur. A common myth is that updating setup and non-setup objects in the same transaction triggers this error. Let’s debunk this myth and clarify best practices for writing efficient Apex code.


What is a Mixed DML Exception?

In Salesforce, setup objects (e.g., User, Profile, PermissionSet) manage org configuration, while non-setup objects (e.g., Account, Contact) handle business data. A Mixed DML exception occurs when you try to modify setup and non-setup objects in the same transaction during DML operations.

However, not all operations trigger this error!


The Myth: Updates Always Cause Errors

Many developers assume that any interaction between setup and non-setup objects (like updates) will throw a Mixed DML error. This is false!


When Does a Mixed DML Exception Actually Occur?

Safe Operations (No Error):

  • Updating setup and non-setup objects in the same transaction.
  • Inserting a non-setup object while updating a setup object (e.g., modifying a User record’s username).

Unsafe Operations (Causes Error):

  • Inserting a setup object (e.g., User) and inserting/updating a non-setup object (e.g., Account) in the same transaction.

Code Examples

✅ Allowed: Update Operations

// Update User (setup) and Account (non-setup) in the same transaction  
User u = [SELECT Id, Username FROM User WHERE Id = :UserInfo.getUserId()];  
u.Username = 'new.email@example.com';  

Account acc = [SELECT Id, Name FROM Account LIMIT 1];  
acc.Name = 'Updated Name';  

update u; // Setup object update  
update acc; // Non-setup object update  
// No exception thrown!  

✅ Allowed: Insert Non-Setup + Update Setup

// Insert Account (non-setup) and update User (setup)  
Account acc = new Account(Name = 'Test Account');  
insert acc; // Non-setup insert  

User u = [SELECT Id, Username FROM User WHERE Id = :UserInfo.getUserId()];  
u.Username = 'updated@example.com';  
update u; // Setup object update  
// No error occurs!  

❌ Unsafe: Insert Setup + Insert Non-Setup

// Insert User (setup) and Account (non-setup) in the same transaction  
User newUser = new User(  
  Alias = 'test',  
  Email = 'test@example.com',  
  Username = 'test@example.com',  
  LastName = 'Test',  
  ProfileId = [SELECT Id FROM Profile LIMIT 1].Id  
);  

Account acc = new Account(Name = 'Test Account');  

// This will throw a Mixed DML error!  
insert newUser;  
insert acc;

Best Practices for Avoiding Errors

  1. Use @future Only for Inserts
  • If you need to insert setup and non-setup objects together, separate them using @future methods.
  • Updates don’t require @future and can coexist in the same transaction.
  1. Write Cleaner Code
    Avoid unnecessary asynchronous logic for updates. Simplify your code by grouping safe operations.
  2. Test with Real Data
    Always validate scenarios in a sandbox to avoid surprises in production.

Conclusion

Understanding Mixed DML exceptions helps you optimize Apex code and avoid overcomplicating transactions. Remember:

  • Updates between setup/non-setup objects are safe.
  • Inserts of non-setup objects paired with setup object updates are allowed.
  • Reserve @future for insert operations involving both object types.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses cookies to offer you a better browsing experience. By browsing this website, you agree to our use of cookies.