1. What is Mixed DML Operation Error?
You will get Mixed DML Operation Error (MIXED_DML_OPERATION) when you try to perform DML on setup objects(User, User Role), along with DML on other sObjects (non-setup Object such as Account, Contact) (or vice versa) in the same transaction.
2. Steps to Reproduce Mixed DML Operation Error
- Create a Flow or Apex Trigger on User Object
- In the Flow or Apex Trigger try to activate the user
- In the same Flow or Apex Trigger try inserting an account
- Try updating a User record so that Flow or the Apex Trigger is fired
Mixed DML Operation Error Example:
MIXED_DML_OPERATION: DML operation on setup object is not permitted after you have updated a non-setup object (or vice versa): User, original object: Account. You can look up ExceptionCode values in the SOAP API Developer Guide. Error ID: 2134391189-480692 (540772277)ok up ExceptionCode values in the SOAP API Developer Guide. Error ID: 2134391189-480692 (540772277)
Why does this error exist?
This restriction exists because some sObjects affect the user’s access to records in the org. You must insert or update these types of sObjects in a different transaction to prevent operations from happening with incorrect access-level permissions. For example, you can’t update an account and a user role in a single transaction.
3. How to Resolve Mixed DML Operation Error?
3.1 Apex
3.1.1 Trigger/Classes
- Create a method that performs a DML operation on one type of sObject
- Create a second method that uses the @future annotation to manipulate a second sObject type
public class MixedDMLError {
public static void insertUserandLead() {
Profile pro = [SELECT Id FROM Profile WHERE Name='Standard User'];
UserRole r = [SELECT Id FROM UserRole WHERE Name='Blogger'];
User usr = new User(alias = 'dy', email='[email protected]',
emailencodingkey='UTF-8', lastname='Yadav',
languagelocalekey='en_US',
localesidkey='en_US', profileid = pro.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='[email protected]');
insert usr;
Handler.insertLead(new Lead(lastname = 'Yadav'));
}
}
public class Handler {
@future
public static void insertLead(Lead testLead) {
insert testLead;
}
}
3.1.2 Test Classes
Test methods allow for performing mixed Data Manipulation Language (DML) operations that include both setup sObjects and other sObjects if the code that performs the DML operations is enclosed within System.runAs method blocks. You can also perform DML in an asynchronous job that your test method calls.
@isTest
private class MixedDMLErrorTestClass {
static testMethod void mixedDMLErrorTestMethod() {
User usr;
Lead testLead;
User thisUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()];
System.runAs (thisUser) {
Profile profStandard = [SELECT Id FROM Profile WHERE Name='Standard User'];
UserRole roleBlogger = [SELECT Id FROM UserRole WHERE Name='Blogger'];
usr = new User(alias = 'dyadav01', email='[email protected]',
emailencodingkey='UTF-8', lastname='Yadav',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id, userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='[email protected]');
insert usr;
testLead = new Lead(lastname ='Dinesh');
insert testLead;
}
}
}
3.2 Flows
3.2.1 Screen Flow
Add a Screen Element or Local Action between Updating User and Creating Lead Actions
3.2.2 Autolaunched Flow
Add a Pause Element between Updating User and Creating Lead Actions
3.2.3 Record-Triggered and Platform Event-Triggered Flows
Since Pause Element is not available in Record-Triggered and Platform Event-Triggered Flows. Using Pause Element is not an option. A possible solution could be to separate the User Activation and Lead Creation process into two different flows. Create an Apex Invocable Action to call the second flow asynchronously. Use the Invocable Apex Action in User Activation flow to invoke Lead Creation Flow.