anusha(salesforce developer)

Thursday, 23 June 2016

MIXED_DML_OPERATION error in Salesforce

You can easily run into this error if you are trying to perform DML on setup and non-setup objects in the same transaction.


Non-Setup objects are standard objects like Account or any custom object.

Setup objects are Group1, GroupMember, QueueSObject, User2, UserRole, UserTerritory, Territory, etc..

For example, you cannot insert an account and then insert a user or a group member in a single transaction.

Test methods allow for performing mixed DML operations between the sObjects listed earlier and other sObjects if the code that performs the DML operations is enclosed within System.runAs method blocks. This enables you, for example, to create a user with a role and other sObjects in the same test.

If we perform DML operation on standard/custom object and global objects(User, UserRole, Group, GroupMember, Permission Set, etc...) in same transaction this error will come.
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 @futureannotation.

public class TriggerUtility {
 /*
 1. Following future method execute asynchronously (whenever server is free it will execute in future context).
 2. We should not declare @future method in Apex Trigger.
 3. @future method should be always static.
 4. @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.
 5. @future method should not contain return type. Always it should be void.
 6. 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.
 7. We cannot perform synchronous call outs from Apex Trigger.
 */
 //Below is the example for the future method -
 @future(callout = true)
 public static void processAsync(primitive parameters) {
  //Logic to insert/update the standard/custom object.
 }
}

1 comment: