Asynchronous Apex

Definition

Asynchronous Apex code in salesforce refers to Future Method/Batch Classes and Queueable Methods.

This type of code runs when the salesforce server has available resources and the current code does not stop for the asynchronous part to be executed.

This type of code is used to make callouts into third party systems and also to do processing in asynchronous code.

NOTE :

The only thing to keep in mind while using these methods is that you cannot call asynchronous methods from asynchronous methods, that is you cannot call a future method from another future method and the same for queueable methods. But we can call a future method/batch class from a queueable method and we can call a queueable method from a future method/batch class.

Future Methods

Future Methods are static methods which follow the following rules :

  • We have to use the @future annotation in the method declaration.
  • Future methods must be static methods, and can only return a void type.
  • The parameters in future methods can only 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 parameters.

Code Syntax :

         public class FutureExample { 

	                @Future
	              public static void myFuture (list listofids)
	             {
		           // do processing
	               }

                 }

Example :

Let’s say if we want to update some account records from an apex trigger in an asynchronous method and update the account description to ‘Salesforce Drillers’. So we can create a future method like this :

           public class AccountFuture { 

	           @Future
	           public static void updateAccounts (list accIds)
	           {
		           list accList = [SELECT Id,Name,Description FROM Account];

		           for(Account ac: accList)
		           {
		           	ac.Description = ‘Salesforce Drillers’;
		           }

		           update acclist;
	           }

           }

And then we can call this method from apex trigger like this :

trigger accountTrigger on Account (after insert)
{
set accIds = new set ();

for( Account ac : trigger.new)
{
	accIds.add(ac.Id);
}

// Call the future method
	AccountFuture.updateAccounts(accIds);
}

Notes while using Future Methods :

  • If we want to do callouts from a future method then we need to add @Future (callout = true) to the notation.
  • Future methods are not the best choice if we want to pass object records or a wrapper class as a parameter.
  • We have no way to determine if a future method has finished processing with code, we can only check with ‘apex jobs’.

Queueable Apex

This was introduced to overcome the Future method limitation of not being able to pass non-primitive parameters and not able to track the execution by code. These follow the following rules :

  • A queueable class must implement the queueable interface.
  • Each queueable class has an execute method which runs asynchronously.
  • When we call a queueable method, it returns an job id which can be used to query the status of the execution of the class by querying on the ‘AsyncApexJob’ object.

Code Syntax :

public class QueueableClass implements Queueable {
 
    public void execute(QueueableContext context) {
        
// do processing   
    }
} 

Calling a Queueable Class :

ID jobID = System.enqueueJob(new QueueableClass());

Querying the Status of a Job :

String jobStatus = [SELECT Status,NumberOfErrors FROM AsyncApexJob WHERE Id=:jobID].Status;

The returned status value can help us determine if the job has finished or is still running.

Passing Object Records in Queueable Classes :

public class QueueableClass implements Queueable {

    public list acc;
 
    public void execute(QueueableContext context) {
        
// do processing   
    }
} 

And call this like this :

QueueableClass obj = new QueueableClass();
obj.acc = [SELECT Id,Name FROM Account];

ID jobID = System.enqueueJob(obj);

Example :
For this example, we can implement the same functionality that we implemented in the future method. That was to update the description on all new Accounts to ‘Salesforce Drillers’ in a different transaction.

Here is how we would implement that via a queueable class :

public class AccountQueueable implements Queueable {

    public list acc;
 
    public void execute(QueueableContext context) {
        	list accToUpdate = new list ();

for(Account ac: acc)
	{
		Account a = new Account();
		a.Id = ac.Id;
		a.Description = ‘Salesforce Drillers’;
		accToUpdate.add(a);
	}

update accToUpdate;
    }
} 

And then call this queueable class from an apex trigger :

trigger accountTrigger on Account (after insert)
{
	AccountQueueable obj = new AccountQueueable();
	Obj.acc = trigger.new;
	
	// Call the queueable class
           system.enqueuejob(obj);
}

Note: how we didn’t have to query any Account records again in the queueable class since we can directly pass the trigger. But since the trigger.new is read only in an after trigger, we had to declare a separate list called “accToUpdate” which is updated at the end of the queueable class.

Subscribe Now