Asynchronous Apex in Salesforce: Optimizing Operations

Asynchronous Apex in Salesforce: Optimizing Operations

An asynchronous process is a process or function that executes a task “in the background” without the user having to wait for the task to finish.

We’ll typically use asynchronous apex for callouts to external system operations that require higher limits, and code that needs to run at a certain time. 

The key benefits of asynchronous processing include:

  • User efficiency
  • Scalability
  • Higher Limits

 

  1. Batch Apex

Batch Apex is used to run large jobs (think thousands or millions of records!) that would exceed normal processing limits.

Using Batch Apex, we can process records asynchronously in batches (hence the name, “Batch Apex”) to stay within platform limits. 

If you have a lot of records to process, for example, data cleansing or archiving, Batch Apex is probably your best solution.

 Batch Apex Syntax

To write a Batch Apex class, class must implement the Database.Batchable interface and include the following three methods:

  1. Start

Syntax: 

global (Database.QueryLocator | Iterable<sObject>)        start(Database.BatchableContext bc) {}

Description:

Collect the records or objects to pass to the interface method execute, call the start method at the beginning of a batch Apex job.

This method returns either a Database.QueryLocator object or an iterable that contains the records or objects passed to the job.

When you’re using a simple query (SELECT) to generate the scope of objects in the batch job, use the Database.QueryLocator object.

If you use a QueryLocator object, the governor limit for the total number of records retrieved by SOQL queries is bypassed. 

For example, a batch Apex job for the Account object can return a QueryLocator for all account records (up to 50 million records) in an org

Use the iterable to create a complex scope for the batch job. You can also use the iterable to create your own custom process for iterating through the list

  1. Execute 

Syntax:  

global void execute(Database.BatchableContext BC, list<P>){}

Description:

To do the required processing for each chunk of data, use the execute method. 

This method is called for each batch of records that you pass to it.

This method takes the following:

  1. A reference to the Database.BatchableContext object.
  2. A list of sObjects, such as List<sObject>, or a list of parameterized types. If you are using a Database.QueryLocator, use the returned list.

Batches of records tend to execute in the order in which they’re received from the start method. 

However, the order in which batches of records execute depends on various factors. The order of execution isn’t guaranteed.

  1. Finish

Syntax:

global void finish(Database.BatchableContext BC){}

 Description:

     To send confirmation emails or execute post-processing operations, use the finish method. This method is called after all batches are processed.

2. Future Method

A future method runs in the background, asynchronously. 

When to use Future Method:

  • We can call a future method for executing long-running operations,  such as callouts to external Web services or any operation we’d like to run in its own thread, on its own time. 
  • We can also use future methods to isolate DML operations on different sObject types to prevent the mixed DML error.

 

  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.
               Future Method can’t take standard or custom object as argument.

global class SomeClass {

  @future(callout=true)

  public static void someFutureMethod(List<Id> recordIds) {

    List<Account> accounts = [Select Id, Name from Account Where Id IN :recordIds];

    // process account records to do awesome stuff

  }

}

 

Best Practise:

  • Ensure that future methods execute as fast as possible.
  • If using Web service callouts, try to bundle all callouts together from the same future method, rather than using a separate future method for each callout
  • Methods with the future annotation 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 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

  • We can’t call a future method from a future method. Nor can we invoke a trigger that calls a future method while running a future method
  • We’re limited to 50 future calls per Apex invocation

 

3. Queueable Apex

We took simplicity of future methods and the power of Batch Apex and mixed them together to form Queueable Apex.  It gives a simplified interface without “start” and “finish” methods and even allows us to utilize more than just primitive arguments!

It is called by a simple System.enqueueJob() method, which returns a job ID that you can monitor.

Queueable Apex Benefits:

 Non-primitive types:Queueable class can contain member variables of non-primitive data   types, such as sObjects or custom Apex types. Those objects can be accessed when the job executes.

 Monitoring: When we submit a job by invoking the System.enqueueJob method, the method returns the ID of the AsyncApexJob record. e can use this ID to identify your job and monitor its progress, either through the Salesforce user interface in the Apex Jobs page, or programmatically by querying your record from AsyncApexJob.

Chaining jobs: We can chain one job to another job by starting a second job from a running job. Chaining jobs is useful if we need to do some sequential processing.

Queueable Syntax

public class SomeClass implements Queueable { 

    public void execute(QueueableContext context) {

        // awesome code here

    }

}

Chaining Jobs

  • One of the best features of Queueable Apex is “job chaining”, If we need to run jobs sequentially, Queueable Apex could make life much easier. 
  • To chain a job to another job, submit the second job from the execute() method of queueable class. 
  • We can add only one job from an executing job, which means that only one child job can exist for each parent job
  • We can add up to 50 jobs to the queue with System.enqueueJob in a single transaction
  • When chaining jobs, you can add only one job from an executing job with ‘System.enqueueJob’, which means that only one child job can exist for each parent queueable job