Interview Series: Future Methods

Interviewer: Why do we use Future Methods?

Interviewee: 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.

Interviewer: Can you write the syntax of a future method?

Interviewee: Methods with the future annotation must be static methods, and can only return a void type.

global class FutureClass
{
@future
public static void myFutureMethod()
{
// Perform some operations
}
}

Interviewer: What kinds of parameters supported in Future methods?

Interviewee: You can pass primitive data types, arrays of primitive data types, or collections of primitive data types as parameters. No sObjects OR objects as arguments can be passed.

Interviewer: Why sobject type parameters are not supported in Future methods?

Interviewee: The reason why sObjects can’t be passed as arguments to future methods is that 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.

Interviewer: What could be the workaround for sobject types?

Interviewee: To work with sObjects, 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
// Process records
}
}

Interviewer: How can I perform Callouts from Future methods?

Interviewee: We need to add a parameter callout=true in @future.

global class FutureMethodExample
{
@future(callout=true)
public static void doCallouts(String name)
{
// Perform a callout to an external service
}
}

Interviewer: How Can I call a future method?

Interviewee: You can invoke future methods the same way you invoke any other method.

FutureMethodExample.doCallouts('Account');

Interviewer: Can I Write the Above statement in a Batch Job?

Interviewee: No you can’t, because Calling a future method is not allowed in the Batch Jobs.

Interviewer: Can I write a future call in Trigger?

Interviewee: Yes, you can.

Interviewer: So, consider a case, I have Written a future call in the Account’s trigger update operation. and I have a batch job running on Account records and does DML on them. Will the future call be invoked after DML?

Interviewee: Since you are in batch context, the trigger runs in the same context too, So as soon as the Account records get updated through the batch process or through any future method, the trigger would throw an exception saying “Future method cannot be called from a future or batch method” as a future method cannot be invoked from future or batch method execution context.

Interviewer: How can avoid this Exception condition, Without using try-catch?

Interviewee: We can update the trigger logic to leverage the System.isFuture() and System.isBatch() calls so that the future method invocation is not made if the current execution context is future or batch.

trigger AccountTrigger on Account (after insert, after update) {if(!System.isFuture() && !System.isBatch())// future call}

Interviewer: So In Any case, I can’t call a future method from a batch Job?

Interviewee: Calling a future method is not allowed in the Execute method, But a web service can be called. A web service can also call an @future method. So, we can define a web service having a future method invocation and call the web service from the execute method of Batch Job.

Interviewer: How Many Future methods can be defined in a Class?

Interviewee: Any number of. There are no restrictions as such.

Interviewer: Take the below case,

global class FutureMethodExample
{
@future(callout=true)
public static void doCallouts(String name)
{
// Perform a callout to an external service
doCallouts2(name);
}@future
public static void doCallouts2(String name)
{
// Perform a callout to an external service
}
}

How many future calls will the above code invoke?

Interviewee: This code is an invalid code as a future method can’t invoke another future method.

Interviewer: If I want to call a future method from a future method, what could be the solution?

Interviewee: Workaround could be calling a web service that has future invocation.

Interviewer: What are the other use cases of using a future method?

Interviewee: We can also use future methods to isolate DML operations on different sObject types to prevent the mixed DML error.

Interviewer: What is a Mixed DML error?

Interviewee: there are 2 kinds of sObjects in salesforce.

  1. Non-Setup: Account, opportunity, etc
  2. Setup: User, groups, etc

In a single transaction Or execution context, If you are performing DML on both kinds, the system doesn’t allow it and throws an exception called Mixed DML exception, stating that a transaction can not have Mixture of DML operation(Setup and Non-Setup)

Interviewer: How Future method helps in avoiding Mixed DML errors?

Interviewee: We can shift DML operations of a particular kind in the Future scope. Since both the DML operations are isolated from each other, the transaction doesn’t fail.

For example:

public class MixedDMLFuture {
public static void useFutureMethod() {
// First DML operation
Account a = new Account(Name='Acme');
insert a;

// This next operation (insert a user with a role)
// can't be mixed with the previous insert unless
// it is within a future method.
// Call future method to insert a user with a role.
Util.insertUserWithRole(
'abc.com', 'Test',
'acb.com', 'Test2');
}
}

Interviewer: Once I call a future method, How can I trace its execution?

Interviewee: Salesforce uses a queue-based framework to handle asynchronous processes from such sources as future methods and batch Apex. So, We can check the apex jobs if it has run or not.

But if it in the queue, and resources are not available, It won’t show up on Apex jobs Page, So we can poll AsyncApexJob object to get its status.

However, future methods don’t return an ID, so We can’t trace it directly. We can use another filter such as MethodName, or JobType, to find the required job.

Interviewer: How to test a future method?

Interviewee: 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.

Interviewer: What are some limitations of future methods?

Interviewee: Some of the limitations are

  1. It is not a good option to process large numbers of records.
  2. Only primitive data types supported.
  3. Tracing a future job is also typical.
  4. Can’t call future from batch and future contexts, 1 call from queueable context is allowed.

--

--

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Vimal Tiwari

Vimal Tiwari

Engineer @Google | Content Creator (Linkedin, Quora & Medium) | https://vimaltiwari2612.github.io