Asynchronous Apex in Salesforce : Future Methods
Future Apex is used to run processes in a separate thread, at a later time when system resources become available.
A future method runs in the background, asynchronously. You can call a future method for executing long-running operations, such as callouts to external Web services or any operation you’d like to run in its own thread, on its own time. You can also use 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. You can call 50 future methods per transaction.
Things to Remember:
- Methods are annotated with @future annotation.
- Use the future annotation to specify that these methods that are executed asynchronously.
- Methods with future annotation must be static methods.
- Methods with future annotation can only return a void type.
- The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types.
- Future methods are not guaranteed to execute in the same order as they are called.
- When using future methods, it’s also possible that two future methods could run concurrently, which could result in record locking and a nasty runtime error if the two methods were updating the same record.
- The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types; future methods can’t take objects as arguments.
- Future methods won’t necessarily execute in the same order they are called. In addition, it’s possible that two future methods could run concurrently, which could result in record locking if the two methods were updating the same record.
- Future methods can’t be used in Visualforce controllers in getMethodName(), setMethodName(), nor in the constructor.
- You’re limited to 50 future calls per Apex invocation, and there’s an additional limit on the number of calls in a 24-hour period. For more information on limits, see the link below.
# Future Method Syntax:
Future methods must be static methods, and can only return a void type. The specified parameters must be primitive data types, arrays of primitive data types, or collections of primitive data types. Notably, future methods can’t take standard or custom objects as arguments. A common pattern is to pass the method a List of record IDs that you want to process asynchronously.public class MyClass {
@future
public static void myFutureMethod(List<Id> recordIds) {
List<Account> accounts = [Select Id, Name from Account Where Id IN :recordIds];
// Your code here
}
}
How to define a method as future?
- Use the annotation @future at the top of the method.
- Future methods must be always static and have a return type as void.
Public class AsyncClass{
@future
Public static void asyncMethod() {
//future code goes here
}
}
What is a Mixed DML Exception?
- 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 @future annotation.
How to resolve Mixed DML Exception?
Synchronous Class
public class SynchronusClass {
public static void synchronusMethod() {
PermissionSet perSet = new PermissionSet();
perSet.Label = 'Apex Set';
perSet.Name = 'ApexSet';
insert perSet;
AsynchronusClass.setupNonSetup();
}
}
Asynchronous Class
public class AsynchronusClass {
@future
public static void setupNonSetup() {
Opportunity opp = new Opportunity();
opp.Name = 'Test Opp';
opp.StageName = 'Prospecting';
opp.CloseDate = System.today();
insert opp;
}
}
How to track future methods?
- Setup -> Environments -> Jobs -> Apex Jobs.
- We can track our future methods here.
- See the status and also track method name.
- Get Id of our future method from here.
Using query
SELECT Id, JobType, ApexClassId, Status, NumberOfErrors, MethodName FROM AsyncApexJob where id = '7075g00005cUGj7'
- Either run the query in query editor or in apex class.
- Get the id from Apex Jobs or query all the records from AsyncApexJob object.
What is System.isFuture()?
Use System.isFuture() when we want any apex code to execute only at the time of future call. System.isFuture() return a boolean value (True or False).
SynchronusClass.apxc
public class SynchronusClass {
public static void synchronusMethod() {
if(System.isFuture()) {
System.debug('Run this at future');
} else {
System.debug('Run this when future is not running');
}
//AsynchronusClass.setupNonSetup();
}
}
AsynchronusClass.apxc
public class AsynchronusClass {
@future
public static void setupNonSetup() {
SynchronusClass.synchronusMethod();
}
}
What is @future(callout=true)?
- To make a Web service callout to an external service or API, you create an Apex class with a future method that is marked with (callout=true).
- If we do not use (callout=true) we’ll get the below error at the time of callouts:-
- System.CalloutException: Callout not allowed from this future method. Please enable callout by annotating the future method. eg: @Future(callout=true)
Advantages and Disadvantages of Future Methods:
Advantages of @future annotation:
- We can make a callout from Trigger using @future annotation
- When there are CPU time limit exceptions and SOQL 101 Exceptions we can use @future and push the business logic that's not of that priority to get executed in Asynchronous mode.
- We can increase the request timeout using @future annotation
Disadvantages with @future annotation:
- We cannot invoke a future method within another @future method
- Future methods cannot be used in Batch Apex.
- @future method cannot return any data back.
- We cannot pass complex data types(List, Set, and Map), custom data types to a future method. We always have to send primitive data types.
- You can call up to 50 @future methods per transaction.
Future Method - Video Tutorial:
# Resources:
# Future Method
Comments
Post a Comment