Batch Apex in Salesforce is a powerful tool for processing large amounts of data asynchronously. In this blog post, we’ll explore how to use Database.Stateful to maintain state across the different transactions of a batch job. Specifically, we’ll:
- Explain the
Database.Statefulinterface. - Demonstrate how to track
Database.insertandDatabase.updatesuccesses and failures. - Show an example of how to email success and failure results. Format these results as a CSV file. Send this file to the admin in the
finishmethod.
What is Database.Stateful?
The Database.Stateful interface in Salesforce allows batch classes to retain instance variable values across multiple execution of the batch job transactions, as batch jobs are stateless by default.
- Stateless means that all the instance variables do not retain their values. This happens between the multiple executions of the execute() method of each batch.
- Implementing the
Database.Statefulinterface enables a batch job to preserve instance variable values. This makes it possible to accumulate results. - You can maintain running totals or carry forward any context across multiple
executemethod invocations during the job’s lifecycle.
Stateful vs. Stateless Batch Apex
In Batch Apex, the terms Stateful and Stateless indicate different behaviors. Stateful means the batch job maintains its state between multiple executions of the execute() method. Stateless means it does not.
Stateless Batch Apex
- Default Behavior:
- Each execution of the
executemethod receives a fresh instance of the class, and all instance variables are reset.
- Each execution of the
- Best Suited For:
- Independent processing where no context from previous batches is needed.
Stateful Batch Apex
- Database.Stateful:
- Retains the state of instance variables across multiple executions of the
executemethod and into thefinishmethod.
- Retains the state of instance variables across multiple executions of the
- Use Cases:
- Summarizing data, maintaining running totals, or aggregating results across batches.
- Capturing successes and failures across the job for reporting.
- Drawbacks:
- Performance Impact:
- As the class will be serialized at the end of each execute method to update its internal state.This extra serialization results in longer execution time.
- Heap Usage:
- Retaining too much data in instance variables can lead to heap size governor limits.
- Performance Impact:
Decision-Making: When Do You Need Database.Stateful?
Ask yourself these questions, when you want to decide to use stateful in your batch class:
- “Does one
executemethod need data from a previousexecutemethod?” - “Does the
finishmethod need data collected across all executions?”
- If the answer is ‘Yes’:
UseDatabase.Statefulto retain state across transactions. - If the answer is ‘No’:
Stick to the default stateless behavior to optimize performance.
Best Practices When Using Database.Stateful
- Avoid Static Variables:
- Static variables are reset between batch executions, even in stateful classes.
- Minimize Data Retention:
- Retain only essential information to avoid excessive memory usage.
- Consider Alternatives:
- Explore using Custom Settings, Custom Metadata, or temporary objects to store state if performance is critical.
- Test for Heap Usage:
- Test the batch class with large datasets to ensure it doesn’t exceed heap limits.
- Use Sparingly:
- Most batch jobs do not require
Database.Stateful. Use it only when necessary for your specific use case.
- Most batch jobs do not require
Batch Apex Examples with Stateful Variables and Error Handling
Scenario Overview
Both examples demonstrate batch processing with error tracking and email notifications, commonly used for:
- Mass data updates/insertions
- Data cleanup operations
- Compliance reporting
- Audit trails
Example 1: Account Update Batch
This batch updates Account descriptions and tracks successes/failures.
Code Structure and Explanation
How It Works:
- Stateful Variables
successRecords: Maintains list of successful updates across batch executionserrorRecords: Tracks failed updates with error messages
- Batch Methods
start(): Queries accounts created todayexecute():- Updates account descriptions
- Uses Database.update with partial success (allOrNone=false)
- Records successes and failures in stateful lists
finish():- Converts tracking lists to CSV format
- Sends email with attachments to admin
Example 2: Contact Creation Batch
This batch creates contacts for recent accounts and tracks the results using a wrapper class.
Code Structure and Explanation
How It Works:
- Wrapper Class
- Encapsulates contact creation details
- Provides CSV formatting method
- Stores:
- Account ID
- Contact Name
- Status
- Error Message
- Batch Processing
start(): Queries accounts from last 7 daysexecute():- Creates new contacts
- Uses Database.insert with partial success
- Stores results in wrapper objects
finish():- Generates separate CSVs for successes and failures
- Attaches CSVs to admin email
Key Features in Both Examples:
- State Maintenance with
Database.Stateful:- We use instance variables
successRecordsandfailureRecordsto maintain state across batches.
- We use instance variables
- Capturing Save Results:
- The
Database.updatemethod withfalseallows partial success. We iterate throughDatabase.SaveResultto segregate successes and failures.
- The
- CSV Generation:
- The CSV is constructed as a string with comma-separated values.
- Emailing Results:
- The
Messaging.SingleEmailMessageclass is used to email the CSV as an attachment.
- The
Summary
Using Database.Stateful in a batch class enables you to maintain state and capture cumulative results across multiple executions. By combining this capability with Database.SaveResult and the Salesforce email API, you can effectively monitor and report the outcomes of your batch jobs. This approach ensures transparency and allows administrators to quickly address any issues highlighted in the failure logs.
Start using Database.Stateful in your batch classes today to handle complex, stateful operations with ease!


Leave a comment