Introduction
As a Salesforce developer, I know that working with large data sets in Salesforce is challenging.
Salesforce’s governor limits are strict about how much data you can manipulate at once. When you need to process thousands or millions of records, Batch Apex becomes your best friend.
Batch Apex provides a structured way to handle bulk data, breaking it down into manageable chunks.
In this blog, we’ll walk through the basics of Batch Apex, when to use it, and how to implement it effectively.
What is Batch Apex?
Batch Apex is a special feature in Salesforce that allows developers to process large volumes of records asynchronously.
Unlike standard triggers and apex classes, which run synchronously in Salesforce, Batch Apex lets you perform complex and resource-intensive tasks outside of immediate user interactions.
Using Batch apex, you can perform operations on large data sets without hitting governor limits, as the operations are divided into smaller, more manageable chunks.
When you should use Batch Apex?
You should use Batch Apex whenever you need to:
- Process large volumes of records, typically thousands or more.
- Perform complex operations that require more CPU time than typical synchronous processing allows.
- Execute time-consuming tasks like recalculating complex values, mass updating records, or integrating with external systems.
Some common use cases include:
- Data cleansing and validation on a large scale.
- Scheduled data exports or updates.
- Asynchronous data processing for better system performance.
Anatomy of a Batch Apex Class
Batch Apex in Salesforce is implemented as an Apex class that implements the Database.Batchable interface.
The Batchable interface includes three key methods:
- Start – Sets up the batch job and defines the scope of the data.
- Execute – Processes each batch of records.
- Finish – Wraps up the batch job and performs any final actions.
Here’s a simple example of a Batch Apex class that updates the status of all Account records.
global class AccountStatusBatch implements Database.Batchable {
// Start method to define the scope of records for the batch
global Database.QueryLocator start(Database.BatchableContext bc) {
return Database.getQueryLocator('SELECT Id, Status__c FROM Account WHERE Status__c = \'Inactive\'');
}
// Execute method to process each batch of records
global void execute(Database.BatchableContext bc, List scope) {
for(Account acc : scope) {
acc.Status__c = 'Active';
}
update scope; // Process the batch by updating each Account in the scope
}
// Finish method for post-batch operations
global void finish(Database.BatchableContext bc) {
System.debug('Batch job completed successfully');
// Optional: Send email notification, update a log, or trigger other actions
}
}
Understanding the Database.QueryLocator and Scope
The ‘Start’ method returns a Database.QueryLocator, which retrieves a large dataset and controls the number of records processed.
With QueryLocator, you can specify a scope size that determines how many records are processed in each batch.
Salesforce default scope size is 200, but you can specify anything up to 2,000.
Managing Asynchronous Execution
Batch jobs are asynchronous, meaning they run independently of the user interface, allowing users to continue working without waiting for the job to complete.
To start a batch job, use the following command:
AccountStatusBatch batch = new AccountStatusBatch();
Id batchJobId = Database.executeBatch(batch, 200); // Specifies a batch size of 200
The executeBatch method runs the batch job asynchronously, allowing for better resource management.
You can monitor the progress of the batch job through the Apex Jobs page in Salesforce Setup.
Batch Apex Limits
While Batch Apex is a powerful way of processing records, it has its some limits:
- Number of Batch Jobs: You can have up to five active or scheduled batch jobs simultaneously.
- Batch Size: Each batch can process up to 2,000 records in one go.
- Total Records: You can process up to 50 million records in a single batch job.
It’s crucial to understand these limits and design your batch processes accordingly to avoid hitting governor limits.
Error Handling and Logging in Batch Apex
Error handling in Batch Apex is essential because errors can occur in any batch execution. Here’s a good practice to log errors:
global void execute(Database.BatchableContext bc, List scope) {
List accountsToUpdate = new List();
for (Account acc : scope) {
try {
acc.Status__c = 'Active';
accountsToUpdate.add(acc);
} catch (Exception e) {
System.debug('Error processing account with ID: ' + acc.Id + ', Error: ' + e.getMessage());
// Log the error to a custom object or error logging framework
}
}
if (!accountsToUpdate.isEmpty()) {
update accountsToUpdate;
}
}
Using try-catch blocks within the execute method allows you to gracefully handle errors without causing the entire batch to fail.
Chaining Batch Apex Jobs
If you need to run multiple batch jobs in sequence, you can use chaining.
You can initiate a new batch job from the Finish method of a Batch Apex class.
For Example:
global void finish(Database.BatchableContext bc) {
System.debug('First batch job completed, initiating the next batch job');
SecondBatchJob nextBatch = new SecondBatchJob();
Database.executeBatch(nextBatch, 100);
}
Chaining is useful when you need to perform dependent tasks or when processing records across multiple steps.
Monitoring and Scheduling Batch Apex Jobs
Salesforce allows you to monitor all asynchronous jobs, including batch jobs, through the Apex Jobs page. For recurring batch jobs, you can use Apex Scheduler to run Batch Apex jobs on a scheduled basis.
Here’s an example of how to schedule a batch job to run daily:
public class DailyBatchScheduler implements Schedulable {
public void execute(SchedulableContext sc) {
AccountStatusBatch batchJob = new AccountStatusBatch();
Database.executeBatch(batchJob, 200);
}
}
To schedule the batch job use the following command.
String cronExp = '0 0 12 * * ?'; // Every day at noon
System.schedule('Daily Account Update Batch', cronExp, new DailyBatchScheduler());
Best Practises for Batch Apex
- Optimize Query Performance:
Use selective filters to minimize the number of records processed. - Set Proper Batch Size:
Choose an appropriate batch size to balance governor limits with performance. - Error Logging:
Implement error handling and logging for traceability. - Avoid DML in Loops:
Use bulk processing to avoid governor limits. - Consider Chaining Carefully:
Chain batches only when necessary to avoid complex dependencies.
- Optimize Query Performance:
Conclusion:
Batch Apex is a powerful tool in Salesforce for handling large data volumes and performing asynchronous processing. By understanding how Batch Apex works and following best practices, you can implement scalable and efficient solutions within the governor limits of Salesforce.
Mastering Batch Apex not only ensures your code’s scalability but also enhances the overall user experience by avoiding long-running synchronous operations.
Happy coding!