Back

Apex Batch Q&A

1. What is Batch Apex?

We can call the apex code by creating object for the class (or) if the variables or methods are static then we can call with class name.

Apex Code in the trigger will execute automatically for the DML operations. If you want to execute apex code on a specific time then we should write batch class. With Batch Apex we can process maximum of 50 million records.

Batch Apex is asynchronous (execute in future context).

While writing the batch class we should inherit Database.Batchable interface. Database is a built in global class which contains inner global interface.

2. What are the Batch Apex methods?

Since we are inheriting Database.Batchable interface we should implement all the method prototypes declared in the interface. We should implement the following global methods – start: It will prepare the records to process and execute only one time. execute: It will take the records prepared in start method and split those records into batches and it will execute multiple times. For example if the start method is returning 1000 records then execute method executes 5 times if you don’t mention the batch size (Default Batch Size is: 200). Maximum batch size is: 2000. finish: We can perform post commit logic like sending emails with the success or error information. It will execute only one time. Batch Class Syntax:

//Database is Class provided by Salesforce.
//Batchable is an global interface which is inside of the Database class.
//Batchable include 3 method prototypes: 1. start 2. execute 3. finish
//start and finish methods will execute only one time.
//execute method executes multiple times.
global class BatchUsage implements Database.Batchable , Database.Stateful {
//at a time we can inherit multiple interfaces but we cannot inherit multiple classes.
//By default batch class is stateless (variable info. store in one method cannot be remembered in other method),
//to make it stateful we should inherit Database.Stateful interface.
String name =;
global Database.queryLocator start(Database.BatchableContext bc) {
//From asynchronous to asynchronous we cannot call
//(from batch class we cannot call future mehthod vice versa.).
name += ‘start’;
system.debug(‘@@@Start Method:+name);
//Collects the records to process. It will forward these records to execute method.
//If we use Iterable as return type for this start method it can hold
//max. of 50k records only.
//If we use Database.queryLocator as return type for this start method it can hold
//max. of 50 million records.
return Database.getQueryLocator(‘select id, name, Location__c from Department__c where Location__c = \’\”);
}
global void execute(Database.BatchableContext bc, LIST sObjLst) {
name += ‘execute’;
system.debug(‘@@@Execute Method:+name);
//Split the records forwarded by start method into batches.
//Default batch size is: 200.
//Max. batch size is: 2000.
List depUPdLst = new List();
for(SObject sObj: sObjLst) {
Department__c dept = (Department__c) sObj;//Type Casting.
dept.Location__c =Bangalore;
depUPdLst.add(dept);
}
if(depUPdLst.size() > 0)
update depUPdLst;
}
global void finish(Database.BatchableContext bc) {
name += ‘finish’;
system.debug(‘@@@Finish Method:+name);
//Post Commit logic like sending emails for the success or failures of the batches.
AsyncApexJob a = [select id, Status, NumberOfErrors, JobItemsProcessed,
TotalJobItems, CreatedBy.Email from AsyncApexJob where id =: bc.getJobId()];
Messaging.singleEmailMessage mail = new Messaging.singleEmailMessage();
mail.setToAddresses(new String[]{a.CreatedBy.Email});
mail.setSubject(Batch Class Result);
mail.setHtmlBody(The batch Apex job processed ‘ ++ a.TotalJobItems ++
‘ batches with++ a.NumberOfErrors ++ ‘ failures.);
//sendEmail methods
Messaging.sendEmail(new Messaging.singleEmailMessage[]{mail});
/*** Scheduling in minutes or hours ***/
/*//Create object for schedulable class
SchedulableUsage su = new SchedulableUsage();
//Preparing chron_exp
Datetime sysTime = System.now();
sysTime = sysTime.addminutes(6);
String chron_exp = ” + sysTime.second() + ‘ ‘ + sysTime.minute() + ‘ ‘ +
sysTime.hour() + ‘ ‘ + sysTime.day() + ‘ ‘ + sysTime.month() + ‘ ? ‘ + sysTime.year();
System.schedule(‘Dep Update’+sysTime.getTime(),chron_exp, su);*/
}
}
3. How to schedule batch apex?

To schedule the batch class we should write a separate class by implementing Schedulable interface.

After writing the above mentioned classes to schedule navigate to: Develop > Apex Classes > Schedule Apex.

By clicking on Schedule Apex button we can schedule the batch class through user interface.

Note: Through user interface we cannot schedule in hours/minutes. Schedulable Class Syntax:

global class SchedulableUsage implements Schedulable {
global void execute(SchedulableContext sc) {
BatchUsage bu = new BatchUsage();
//Database.executeBatch(bu);//Default Batch Size is: 200.
Database.executeBatch(bu,1500);//Max. Batch Size is: 2000.
}
}
4.How to schedule batch apex in minutes/hours?

To schedule the batch class in minutes/hours, in the finish method we should use System.schedule method which will take 3 parameters Job Name, Chrone Expression and schedulable class instance name respectively.

/*** Scheduling in minutes or hours ***/
//Create object for schedulable class
SchedulableUsage su = new SchedulableUsage();
//Preparing chron_exp
Datetime sysTime = System.now();
sysTime = sysTime.addminutes(6);
String chron_exp =+ sysTime.second() + ‘ ‘ + sysTime.minute() + ‘ ‘ +
sysTime.hour() + ‘ ‘ + sysTime.day() + ‘ ‘ + sysTime.month() +?+ sysTime.year();
System.schedule(Dep Update+sysTime.getTime(),chron_exp, su);
4.How to maintain the state between the methods of batch class?

By default batch class is stateless (variable value which is stored in one method cannot be remembered in another method).

To maintain the state for the batch class, we should inherit Database.Stateful interface. Scenario: In a set list of emails are stored in execute method. In the finish method that set is not having any emails. What is the reason?

Answer: By default batch class is stateless. Emails which are added to set can be remembered only in execute method. If we try to access the set in finish method you won’t see those emails. In finish method if you want to access those emails of that set we should inherit the interface called Database.Stateful.

5.Is it possible to call batch class from one more batch class?

Yes it is possible, starting with Apex saved using Salesforce API version 26.0, you can call Database.executeBatch or System.scheduleBatch from the finish method. This enables you to start or schedule a new batch job when the current batch job finishes.

For previous versions, you can’t call Database.executeBatch or System.scheduleBatch from any batch Apex method. Note that the version used is the version of the running batch class that starts or schedules another batch job. If the finish method in the running batch class calls a method in a helper class to start the batch job, the Salesforce API version of the helper class doesn’t matter.

6.Is it possible to call future method from a batch class?

We cannot call one asynchronous process from another asynchronous process. Since @future method and Batch Class both are asynchronous we cannot call future method from batch class or we cannot call batch class from the future method.

7..How to cover the code for a batch class?

To cover the code for the batch class we should call the batch class from the inside of the Test.startTest() and Test.stopTest().

Test.startTest();

//Call the batch class from here.

Test.stopTest();

8.How many batch jobs can be active/queued at a time?

Up to 5 batch jobs can be queued or active.

9.Is it possbile to write batch class and schedulable class in a same class?

By implementing Database.Batchable and Schedulable interfaces we can implement the methods in a same class.

Though it is possible it is not recommended to write like this.



Back
Site developed by Nikhil Karkra © 2023 | Icons made by Freepik