softvowels.com

Table of Contents

Batch Apex is usually used to build complex, long-running processes that run on thousands of records (large data volume till 50 million records), at any specific time.

Advantage of Batch Apex

  1. Can query up to 50 million records (Using QueryLocator object)
  2. Every transaction starts with a new set of governor limits, making it easier to ensure that your code stays within the governor execution limits.
  3. If one batch fails to process successfully, all other successful batch transactions aren’t rolled back.
  4. The maximum number of batch executions is 250,000 per 24 hours.

Construction of a Batch Class

public class MyBatchClass implements Database.Batchable<sObject> {
    public (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {
        // collect the batches of records or objects to be passed to execute
    }
    public void execute(Database.BatchableContext bc, List<P> records){
        // process each batch of records
    }
    public void finish(Database.BatchableContext bc){
        // execute any post-processing operations
    }
}

If we go through above then we can see that there are 3 methods defined in the class – start, execute and finish. These we have to define in a Batch class because the class implements an Interface Database.Batchable where these 3 methods are declared. All the methods in the Database.Batchable interface require a reference to a Database.BatchableContext object. Use this object to track the progress of the batch job. Instance method getJobID() belongs to Database.BatchableContext object and returns the ID of the AsyncApexJob object associated with this batch job as a string.

  • start – This method is used to fetch required records on which functionality to be worked upon. This method sends fetched records to execute() method for processing. This method runs only once per Batch class at the beginning. Usually we fetch records to be processed using SOQL here and retuning to Database.QueryLocator. We should tune SOQL to gather the records to execute as quickly as possible. This method may return Iterable object. If we need to do something on records or pre-process records before being passed to the execute method, we might use Custom Iterators. With an Iterable, the governor limit for the total number of records retrieved by SOQL queries is still enforced.
  • execute – This method performs the actual processing on each chunk or “batch” of data passed to the method. The default batch size is 200 records. Remember, chunks or batches of records are not guaranteed to execute in the order they are received from the start method.
    • A reference to the Database.BatchableContext object. There are 2 parameters in this method mentioned below.
    • A list of sObjects, such as List, or a list of parameterized types. If we are using a Database.QueryLocator, use the returned list.
  • finish – This method is used to execute post-processing operations (for example, sending an email) and is called at last once after all batches are processed. This is the method where from we can execute another batch class to perform another complex long running task in synchronous with parent batch class, but in asynchronous way.

Invoking a Batch Class

General step

MyBatchClass myBatchObject = new MyBatchClass();
Id batchId = Database.executeBatch(myBatchObject);

In case, if we want to specify the number of records that should be passed into the execute method for each batch. Sometimes, when governor limits hit then we can minimize the size of each batch chunk. This value must be greater than zero. If the start method of the batch class returns a QueryLocator, the optional scope parameter of Database.executeBatch can have a maximum value of 2,000. But, would suggest to keep default to 200 or minimize the scope.

MyBatchClass myBatchObject = new MyBatchClass();
Id batchId = Database.executeBatch(myBatchObject, 100);

Batch jobs can also be programmatically scheduled to run at specific times using the Apex scheduler, or scheduled using the Schedule Apex page in the Salesforce user interface.

We can view the progress via SOQL or manage your job in the Apex Job Queue.

AsyncApexJob job = [SELECT Id, Status, JobItemsProcessed, TotalJobItems, NumberOfErrors FROM AsyncApexJob WHERE ID = :batchId ];

State in Batch Apex

Batch Apex is typically stateless. Each execution of a batch Apex job is considered a discrete transaction.
If we specify Database.Stateful in the class definition, we can maintain state across all transactions though only instance member variables retain their values between transactions.

Testing Batch Apex

Make sure that the number of records inserted is less than or equal to the batch size of 200 because test methods can execute only one batch. we must also ensure that the Iterable returned by the start() method matches the batch size.

When to use Batch Apex

  1. Basically used for database maintenance jobs. When large volume of data needs to be updated on the basis of a complex long-running functionality.
  2. To work on larger query results than regular transactions allow.

Points to ponder

  • Up to 5 batch jobs can be queued or active concurrently.
  • Up to 100 Holding batch jobs can be held in the Apex flex queue.
  • In a running test, you can submit a maximum of 5 batch jobs.
  • The maximum number of batch Apex method executions per 24-hour period is 250,000, or the number of user licenses in your org multiplied by 200—whichever is greater.
  • Only one batch Apex job’s start method can run at a time in an organization. Batch jobs that haven’t started yet remain in the queue until they’re started.
  • With the QueryLocator object, the governor limit for the total number of records retrieved by SOQL queries is bypassed and we can query up to 50 million records. However, with an Iterable, the governor limit for the total number of records retrieved by SOQL queries is still enforced.
  • Batch classes can be called from Future methods.
  • Batch classes can be called from Queueable Apex.
  • Batch classes can be called from another Batch class. Basically for batch chaining. Calling a batch from another batch’s finish method.
  • Future methods can not be called from the batch class. Error occurs: Future method cannot be called from a future or batch method:
  • Queueable Apex can be called from the batch class.
  • Avoid invoking batch class from trigger. Otherwise, be careful that trigger won’t add more batch jobs than the limit.
  • Using FOR UPDATE in SOQL queries to lock records during update isn’t applicable to Batch Apex.
  • The start, execute, and finish methods can implement up to 100 callouts each.

Hands on

Create 3 classes as mentioned below. Next you need to run each one from Developer Console for your understanding of who can call whom. Comment and uncomment the execution lines and see the magic responses.
1. AsynchronousStudyFuture: Create this class in your personal org coping below code. This class has future methods defined.

public class AsynchronousStudyFuture {

    @future
    public static void aFutureMethod1(){
        System.debug('---Future method: aFutureMethod1() is running');
    }
    
    @future
    public static void aFutureMethod2(){
        System.debug('---Future method: aFutureMethod2() is running');
        aFutureMethod1(); //Calling another future method
    }
    
    public static void justChecking(){
        System.debug('---Running from AsynchronousStudyFuture.justChecking()');
        //aFutureMethod1();//Basic calling of a future method
        //System.enqueueJob(new AsychronousStudyQueueable());//Enqueueing queueable job
        Database.ExecuteBatch(new AsynchronousStudyBatch());
        //aFutureMethod2();//Check for error
    }
}

2. AsynchronousStudyBatch: This is just a simple batch class. For execution purpose we have written a SOQL that you can ignore.

global class AsynchronousStudyBatch implements Database.Batchable<sObject> {
    global Database.QueryLocator start(Database.BatchableContext bc) {
        String strQuery = 'SELECT Id FROM Account';
        return Database.getQueryLocator(strQuery);
    }
    global void execute(Database.BatchableContext bc, List<sObject> records){
        System.debug('---From batch class AsynchronousStudyBatch execute()');
        System.enqueueJob(new AsychronousStudyQueueable());//Enqueueing queueable job
        //AsynchronousStudyFuture.justChecking();
    }    
    global void finish(Database.BatchableContext bc){
        // execute any post-processing operations
    }    
}

3. AsychronousStudyQueueable: This is a simple queueable apex class having only execute() method.

public class AsychronousStudyQueueable implements Queueable {
    
    public void execute(QueueableContext context) {
        System.debug('---Running from Queueable job. AsychronousStudyQueueable class execute');
        //AsynchronousStudyFuture.justChecking();
        //Database.ExecuteBatch(new AsynchronousStudyBatch());
        //System.enqueueJob(new AsychronousStudyQueueable());
    }
}

Developer Console

System.enqueueJob(new AsychronousStudyQueueable());

Database.ExecuteBatch(new AsynchronousStudyBatch());

AsynchronousStudyFuture.justChecking();

Recent Post

Batch Apex is usually used to build complex, long-running processes that run on thousands of records(large data volume till 50 million records), at any specific time. Go through to get concrete understanding.
Salesforce has an annotation @future that we can use defining a method making its execution as asynchronous. For concrete understanding read further.
5 1 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x