Future Methods in Salesforce @future
Future Methods in Salesforce using @future annotation
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.
Future method syntax
global class FutureClass { @future public static void myFutureMethod() { // Perform some operations } }
- Use @future annotation before the method declaration.
- 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.
- 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.
global class FutureMethodRecordProcessing { @future public static void processRecords(List<ID> recordIds){ // Get those records based on the IDs List<Account> accts = [SELECT Name FROM Account WHERE Id IN :recordIds]; // Process records } }
Future method callouts using @future(callout=true)
To allow callout from the future method annotation needs an extra parameter (callout=true) to indicate that callouts are allowed. Here is example
global class FutureMethodExample { @future(callout=true) public static void getStockQuotes(String acctName){ // Perform a callout to an external service } }
Test Class for Future Methods
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.
@isTest private class MixedDMLFutureTest { @isTest static void test1() { User thisUser = [SELECT Id FROM User WHERE Id = :UserInfo.getUserId()]; // System.runAs() allows mixed DML operations in test context System.runAs(thisUser) { // startTest/stopTest block to run future method synchronously Test.startTest(); MixedDMLFuture.useFutureMethod(); Test.stopTest(); } // The future method will run after Test.stopTest(); // Verify account is inserted Account[] accts = [SELECT Id from Account WHERE Name='Acme']; System.assertEquals(1, accts.size()); // Verify user is inserted User[] users = [SELECT Id from User where username='mruiz@awcomputing.com']; System.assertEquals(1, users.size()); } }
Future Method Performance Best Practices
Salesforce uses a queue-based framework to handle asynchronous processes from such sources as future methods and batch Apex. This queue is used to balance request workload across organizations. Use the following best practices to ensure your organization is efficiently using the queue for your asynchronous processes.
- Avoid adding large numbers of future methods to the asynchronous queue, if possible. If more than 2,000 unprocessed requests from a single organization are in the queue, any additional requests from the same organization will be delayed while the queue handles requests from other organizations.
- Ensure that future methods execute as fast as possible. To ensure fast execution of batch jobs, minimize Web service callout times and tune queries used in your future methods. The longer the future method executes, the more likely other queued requests are delayed when there are a large number of requests in the queue.
- Test your future methods at scale. Where possible, test using an environment that generates the maximum number of future methods you’d expect to handle. This helps determine if delays will occur.
- Consider using batch Apex instead of future methods to process large numbers of records.
For more details please refer to official link
To define a future method, simply annotate it with the future annotation, as follows.
6 comments
Skip to comment form
Hi Ankush,
Thanks for Nice Article.
So for long running callout can we use future method if we are getting TimeOut error while doing a callout?
Will it solve the error?
And in which cases we should go for continuation class or Future for long running callout.
Author
We should go for the future, when we don’t want to see an immediate result. You can also set request timeout limit
request.setTimeout(120000);
Hi Ankush,
This article is very helpful, thank you for sharing it.
One question – Can we call @future annotation method inside @future method?
Author
No, you can not.
You can use queueable for that and chain jobs
https://www.sfdcpoint.com/salesforce/queueable-apex-salesforce/
very helpful article .
can we call other future method from one future method ?
No we cannot call one future method from other future method