What are Future Methods ?
When do future method execute?
How to define a future method ?
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
}
}What are the requirements for defining a future method ?
future annotation must be static methods, and can only return a void type.future annotation can’t take sObjects or objects as arguments.What is the reason why sObjects can’t be passed as arguments to future methods ?
How to work with sObjects in future methods if sObjects can’t be passed as arguments to future methods?
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.
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
}
}How to invoke callouts in future methods ?
The @future annotation takes an extra parameter (callout=true) to indicate that callouts are allowed.
global class FutureMethodExample
{
@future(callout=true)
public static void getStockQuotes(String acctName)
{
// Perform a callout to an external service
}
}What are the limitations that future methods have ?
Methods with the future annotation have the following limits:
@future or executeBatch called in a startTest, stopTest block, don’t count against your limits for the number of queued jobs.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. This limit is for your entire org and is shared with all Asynchronous Apex: Batch Apex, Queueable apex, scheduled Apex and future methods.How are the future jobs queued in a transaction ?
How to test future methods ?
future annotation, call the class containing the method in a startTest(), stopTest() code block.startTest method are collected by the system. When stopTest is executed, all asynchronous process 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());
}
}What are the best practices to improve future method performance ?
Salesforce uses a queue-based framework to handle asynchronous processes from such sources as future methods and batch Apex.