Mixed DML operations within a single transaction aren’t allowed. You can’t perform DML on a setup sObject and another sObject in the same transaction. However, you can perform one type of DML as part of an asynchronous job and the others in other asynchronous jobs or in the original transaction. This class contains an @future method to be called by the class in the subsequent example.
public class InsertFutureUser {
@future
public static void insertUser() {
Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
UserRole r = [SELECT Id FROM UserRole WHERE Name='COO'];
User futureUser = new User(firstname = 'Future', lastname = 'User',
alias = 'future', defaultgroupnotificationfrequency = 'N',
digestfrequency = 'N', email = 'test@test.org',
emailencodingkey = 'UTF-8', languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id,
timezonesidkey = 'America/Los_Angeles',
username = 'futureuser@test.org',
userpermissionsmarketinguser = false,
userpermissionsofflineuser = false, userroleid = r.Id);
insert(futureUser);
}
}
A future method runs in the background, asynchronously. You can call a future method for executing long-running operations, such ascallouts to external Web services or any operation you’d like to run in its own thread, on its own time. You can also make use of future methods to isolate DML operations on different sObject types to prevent the mixed DML error. Each future method is queued and executes when system resources become available. That way, the execution of your code doesn’t have to wait for the completion of a long-running operation. A benefit of using future methods is that some governor limits are higher, such as SOQL query limits and heap size limits
To define a future method, simply annotate it with the future annotation, as follows:-
global class FutureClass
{
@future
public static void myFutureMethod()
{
// Perform some operations
}
}
NOTE :-
1) Methods with the future annotation must be static methods 2) can only return a void type 3) The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types 4) Methods with the future annotation cannot take sObjects or objects as arguments. 5) You can invoke future methods the same way you invoke any other method. However, a future method can’t invoke another future method 6) No more than 50 method calls per Apex invocation 7) Asynchronous calls, such as @future or executeBatch, called in a startTest, stopTest block, do not count against your limits for the number of queued jobs 8) The maximum number of future method invocations per a 24-hour period is 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater 9) To test methods defined with the future annotation, call the class containing the method in a startTest(), stopTest() code block. All asynchronous calls made after the startTest method are collected by the system. When stopTest is executed, all asynchronous processes are run synchronously
IMP:- The reason why sObjects can’t be passed as arguments to future methods is because the sObject might change between the time you call the method and the time it executes. In this case, the future method will get the old sObject values and might overwrite them. To work with sObjects that already exist in the database, pass the sObject ID instead (or collection of IDs) and use the ID to perform a query for the most up-to-date record. The following example shows how to do so with a list of IDs
Hi Amith Can u give me small example ..(You can also make use of future methods to isolate DML operations on different sObject types to prevent the mixed DML error)...i didnt get the what is the mixed dml error in this case? sorry if giving u any burden?
Mixed DML operations within a single transaction aren’t allowed. You can’t perform DML on a setup sObject and another sObject in the same transaction. However, you can perform one type of DML as part of an asynchronous job and the others in other asynchronous jobs or in the original transaction. This class contains an @future method to be called by the class in the subsequent example.
public class InsertFutureUser {
@future
public static void insertUser() {
Profile p = [SELECT Id FROM Profile WHERE Name='Standard User'];
UserRole r = [SELECT Id FROM UserRole WHERE Name='COO'];
User futureUser = new User(firstname = 'Future', lastname = 'User',
alias = 'future', defaultgroupnotificationfrequency = 'N',
digestfrequency = 'N', email = 'test@test.org',
emailencodingkey = 'UTF-8', languagelocalekey='en_US',
localesidkey='en_US', profileid = p.Id,
timezonesidkey = 'America/Los_Angeles',
username = 'futureuser@test.org',
userpermissionsmarketinguser = false,
userpermissionsofflineuser = false, userroleid = r.Id);
insert(futureUser);
}
}
1) https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects_test_methods.htm
2) http://www.tgerm.com/2012/04/mixeddmloperation-dml-operation-on.html
Mixed DML operations within a single transaction aren’t allowed. You can’t perform DML on a setup sObject and another sObject in the same transaction. However, you can perform one type of DML as part of an asynchronous job and the others in other asynchronous jobs or in the original transaction. This class contains an @future method to be called by the class in the subsequent example.
Let us know if this will help you
Thanks
Amit Chaudhary
All Answers
To define a future method, simply annotate it with the future annotation, as follows:- NOTE :-
1) Methods with the future annotation must be static methods
2) can only return a void type
3) The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types
4) Methods with the future annotation cannot take sObjects or objects as arguments.
5) You can invoke future methods the same way you invoke any other method. However, a future method can’t invoke another future method
6) No more than 50 method calls per Apex invocation
7) Asynchronous calls, such as @future or executeBatch, called in a startTest, stopTest block, do not count against your limits for the number of queued jobs
8) The maximum number of future method invocations per a 24-hour period is 250,000 or the number of user licenses in your organization multiplied by 200, whichever is greater
9) To test methods defined with the future annotation, call the class containing the method in a startTest(), stopTest() code block. All asynchronous calls made after the startTest method are collected by the system. When stopTest is executed, all asynchronous processes are run synchronously
IMP:-
The reason why sObjects can’t be passed as arguments to future methods is because the sObject might change between the time you call the method and the time it executes. In this case, the future method will get the old sObject values and might overwrite them. To work with sObjects that already exist in the database, pass the sObject ID instead (or collection of IDs) and use the ID to perform a query for the most up-to-date record. The following example shows how to do so with a list of IDs
Let us know if this will help you
Thanks
Amit Chaudhary
1) https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_dml_non_mix_sobjects_test_methods.htm
2) http://www.tgerm.com/2012/04/mixeddmloperation-dml-operation-on.html
Mixed DML operations within a single transaction aren’t allowed. You can’t perform DML on a setup sObject and another sObject in the same transaction. However, you can perform one type of DML as part of an asynchronous job and the others in other asynchronous jobs or in the original transaction. This class contains an @future method to be called by the class in the subsequent example.
Let us know if this will help you
Thanks
Amit Chaudhary