Batch Apex in Salesforce

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

To use batch Apex, write an Apex class that implements Database.Batchable interface and make your class global

Implement the following 3 methods

  • start()
  • execute()
  • finish()

The default batch size is 200.

Minimum batch size ?

Maximum batch size?

Understanding Methods

Start: This method is called at the starting of a batch job to collect the data on which the batch job will be operating. It breaks the data or record into batches

Syntax:

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

Execute: This method executes after the Start method, and it does the actual processing for each batch, separately.

Syntax:

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

Finish: This method will be called at last. Since this method is called in the end, it is responsible to perform post-processing operations such as sending an email. When this process is called all batches are already executed.

Syntax:

global void finish(Database.BatchableContext BC) {}

Note:

If your code accesses external objects and is used in batch Apex, use Iterable<sObject> instead of Database.QueryLocator.

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

Example: Add sfdcAmplified to account name

global class BatchApexExample implements Database.Batchable<sObject> {
    global Database.QueryLocator start(Database.BatchableContext BC) {
        // collect the batches of records or objects to be passed to execute
         
        String query = 'SELECT Id, Name FROM Account limit 5';
        return Database.getQueryLocator(query);
    }
     
    global void execute(Database.BatchableContext BC, List<Account> accList) {
        
        // process each batch of records default size is 200
        for(Account acc : accList) {        
            // Update the Account Name 
            acc.Name = acc.Name + 'sfdcamplified';
        }
        try {
            // Update the Account Record
            update accList;
         
        } catch(Exception e) {
            System.debug(e);
        }
         
    }   
     
    global void finish(Database.BatchableContext BC) {
        // execute any post-processing operations like sending email
    }
}

TestClass

@isTest
private class BatchApexExampleTest {
    static testmethod void test() {
        // Create test accounts to be updated by batch
    List<Account> accList = new List<Account>();

    for (Integer i=0;i<5;i++) {
        Account ac = new Account(Name = 'Account ' + i);
        accList.add(ac);
    }
    insert accList;
 
        Test.startTest();
            BatchApexExample b = new BatchApexExample();
        Database.executeBatch(b);
        Test.stopTest();
        // Verify accounts updated
    Account[] accUpdatedList = [SELECT Id, Name FROM Account];
    System.assert(accUpdatedList[0].Name.Contains('sfdcamplified'));
    }
}

Invoking a Batch Class

Database.executeBatch(new BatchApexExample(),100);

Monitoring Batch Apex

To monitor or stop the execution of the batch Apex job, from Setup, enter Apex Jobs in the Quick Find box, then select Apex Jobs.

Batch Apex Chaining

With the onset of API version 29.0 and after, a batch class can be chained to another batch class.

Chaining of batch apex kickstarts the execution of the chained batch class once the execution of the base batch class is finished. At maximum, only 5 Batch jobs can be chained to one another.

global database.querylocator start(Database.BatchableContext BC)
{
//start method logic here
}
global void execute(Database.BatchableContext BC, List<sObject> scope)

{
//start method logic here

}
global void finish(Database.BatchableContext BC)
{
//Batch Chaining Step Starts here
AccountBatch accBatch = new AccountBatch ();
Id batchProcessId = Database.executeBatch(accBatch);

//finish method logic here
}

Why use Batch Apex in Salesforce instead of the normal Apex?

There are various reasons why Batch Apex is better than normal Apex.

  • SOQL queries: Normal Apex uses 100 records per cycle to execute SOQL queries. Whereas, Batch Apex does the same in 200 records per cycle.
  • Retrieval of SOQL queries: Normal Apex can retrieve 50,000 SOQL queries but, in Batch Apex, 50,000,000 SOQL queries can be retrieved.
  • Heap size: Normal Apex has a heap size of 6 MB; whereas, Batch Apex has a heap size of 12 MB.
  • Errors: When executing bulk records, Normal Apex classes are more vulnerable to encountering errors as compared to Batch Apex

Advantages:

  • Every transaction starts with a new set of governor limits, making it easier to ensure that your code stays within the governor execution limits.
  • If one batch fails to process successfully, all other successful batch transactions aren’t rolled back.

Batch Apex Interview Questions

1. How many active batches(running parallel) can be allowed at a time?

Salesforce by default allows 5 active batches running at a time and other batches will be in queue for running

2. How can we schedule batch class to run in future only once from the specified minutes from current time.

public static String scheduleBatch(Database.Batchable batchable, String jobName, Integer minutesFromNow)

or

public static String scheduleBatch(Database.Batchable batchable, String jobName, Integer minutesFromNow,Integer batchSize)

3.How to calculate the batch size if we are making any call out from the batch class execute method?

Basically in salesforce we have limitation of 100 call outs for a transaction.When it comes to batch class each execute method call will be considered as one transaction.So,in this case your batch size must be calculated in such way

Batch size = (No of callouts allowed for single transaction /total number of call outs for each record) – 1;

Batch size = (100 /total number of call outs for each record) – 1;

4. How to stop all the running batches related to a particular batch classes before scheduling the same batch class from the schedule class

global class CaseCreationonSchedular implements Schedulable
{
global void execute(SchedulableContext SC)
{

for(AsyncApexJob ap: [SELECT Id, ApexClass.Name,createddate, JobType, Status, JobItemsProcessed, MethodName, ParentJobId FROM AsyncApexJob Where ParentJobId!=Null AND JobType IN(‘BatchApex’,’BatchApexWorker’) And ApexClass.Name=’YourBatchClassName’ And Status NOT IN(‘Completed’,’Aborted’)])
{
System.abortJob(ap.ParentJobId);

}
YourBatchClassName cls = new YourBatchClassName();
DataBase.executeBatch(cls);
}
}

5.How can we schedule a batch class to run every 10 or 5 or 2 mins.

Salesforce haven’t provided wild card entries (* every,- range,/,?) in place of minutes and seconds.So,if you want schedule a class to run every 10 minutes you have to schedule same class 6 times (60min/6) with diff batch name ,for 5 mins 12 times and for 2 mins 30 times..As the time interval keeps going down schedule the same class goes up which is an irritating thing to monitor or even it’s very hard to handle these many jobs.

For this we can simply do this in the code so that at any given point of time you will have only schedule job running for the same.

global class CaseCreationonSchedular implements Schedulable
{
public void execute(SchedulableContext scon)
{
System.abortJob(scon.getTriggerId()); // abort already running schedule job
Decimal nextInterval = System.Label.nextIntervalTime; // config to decide next interval 2,5 or 10 mins etc..
System.schedule(‘CaseCreationonBatch – ‘+String.valueOf(DateTime.now()), ‘0 ‘+DateTime.now().addMinutes(Integer.valueOf(nextInterval)).minute()+’ */1 ? * *’, this); //Schedule the class to run with specified time

Database.executeBatch(new YourBatchClassName()); // Call you batch class

}
}

6.Why to use Batch class as we already having data loader to process the bulk data.

Agree with this point if and only if the data needs to be updated is static or predefined or which can be done through excel.

We will choose batch class if we have to perform some custom calculations at run time or if you want to run some complex logic which can’t be driven by excel sheets in those cases we have to go with batch classes.

Examples:

Do some relationship quires to update the data.
Make a call out to get the some information related to each record.
7.How many times the execute method will be executed to process the 1234 records.

It depends on your batch size what you have configured at the time of calling the batch class from schedule class.

Execution method count = Total No Of Records/Batch Size (Any decimal ceil it to upper value)
If you haven’t set any batch size then – 1234/200 = 6.17 = 7 times execute method will be called

8.What is the maximum size of a batch that we can set up ?

2000

9.What is the minimum batch size we can set up is?

1

10.What is the default size of batch if we haven’t configured at the time of execution?

200

11.What is Apex Flex Queue?

At a time salesforce allolws 5 batches to be running or to be in queued state.So,if you have consumed all these 5 limits and if system has received one or more batch execution request all these waiting batch will be stored in this Apex Flex Queue.

12. What is the maximum number of batch classes allowed in Apex Flex Queue for execution?

100

13.How can we do chaining of batch jobs?

we can do this by simply calling the chained batch/second batch class from the finish method of the first batch class.

Why to call only from the finish method why not from execute?because the execute method will gets invoked multiple times based on the volume of the records and batch size.So,if your calling it from execute method then the chaining class will get called multiple times which is not an suggested way of doing.

We can also use the Queueable Apex for chaining of the jobs.

 

Did you enjoy this article?
Signup today and receive free updates straight in your inbox.
I agree to have my personal information transfered to MailChimp ( more information )
50% LikesVS
50% Dislikes