A mixed DML Operation Error in Salesforce comes when you try to perform DML operations on setup and non-setup objects in a single transaction. DML operations on certain sObjects, sometimes referred to as setup objects(User), can’t be mixed with DML on other sObjects(Standard/Custom Objects) in the same transaction.
How do you resolve a mixed DML exception?
- To avoid this error, we should perform DML operation on standard/custom object records in a different transaction.
- In general all the apex classes and apex triggers execute synchronously (execute immediately).
- If we perform DML operation on standard/custom object records asynchronously (execute in future context), we can avoid MIXED-DML-OPERATION error.
- To execute logic asynchronously keep the logic in an apex method (in a separate apex class, not in same apex trigger) which is decorated with @future annotation.
In the below example, Account and User records are inserted in the
same transaction.
This is will throw the Mixed DML Exception.
This is will throw the Mixed DML Exception.
public class MixedDMLError {
public static void myMethod() {
Account a = new Account(Name='XploreSFDC');
insert a;
Profile p=[SELECT Id FROM Profile WHERE
Name='Standard User'];
UserRole r = [SELECT Id FROM UserRole WHERE Name='CEO'];
User usr = new User(alias = 'XploreSFDC',
email='XploreSFDC@XploreSFDC.com',
emailencodingkey='UTF-8', lastname='Max',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id,
userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='XploreSFDC@XploreSFDC.com');
insert usr;
}
}
Let us see how we can fix it
public class MixedDMLErrorFixed {
public static void myMethod() {
Account a = new Account(Name='XploreSFDC');
insert a;
FutureDemo.insertUser();
}
}
public class FutureDemo {
@future
public static void insertUser() {
Profile p=[SELECT Id FROM Profile WHERE
Name='Standard User'];
UserRole r = [SELECT Id FROM UserRole WHERE Name='CEO'];
User usr = new User(alias = 'XploreSFDC',
email='XploreSFDC@XploreSFDC.com',
emailencodingkey='UTF-8', lastname='Max',
languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id,
userroleid = r.Id,
timezonesidkey='America/Los_Angeles',
username='XploreSFDC@XploreSFDC.com');
insert usr;
}
}
Few Point to keep in mind:
- Future method execute asynchronously (whenever server is free it will execute in future context).
- We should not declare @future method in Apex Trigger.
- @future method should be always static.
- @future method accepts only primitive data types (Integer, String, Boolean, Date, etc…) as parameters and it won’t accept non-primitive data types (sObject,Custom Objects and standard Objects etc.. ) as parameters.
- @future method should not contain return type.
- From an apex trigger we can make only make asynchronous call outs. To make call out we should include “callout = true” beside the future @annotation.
- We cannot perform synchronous call outs from Apex Trigger.
No comments:
Post a Comment