
When and Where to use Database.Stateful in Batch Apex
When writing batch apex, the values and state of the batch is reset per transaction. If there is a need to reference a value from the previous transaction or maintain the same value in each transaction then Salesforce provides a few ways to do so. One of these is using Databa.Stateful.
In this article, we will dive deep into what Database.Stateful can be used and how to use it.
What is Database.Stateful used for?
Database.Stateful can be used to maintain and persist a value in a variable for each transaction of the batch. This becomes useful when the same value is needed for multiple transactions.
When Database.Stateful is used in a batch then the entire of state of the batch is maintained. Maintaining state is useful for counting or summarizing records as they’re processed.
For example, suppose your job processed opportunity records. You could define a method in execute to aggregate totals of the opportunity amounts as they were processed.
If you don’t specify Database.Stateful, all static and instance member variables are set back to their original values.
How to use Database.Stateful?
Database.stateful can be used by adding the Database.Stateful keyword after Database.Batchable<sObject> keyword.
public class SumOpportunityTotal
implements Database.Batchable<sObject>, Database.Stateful{
public integer Summary;
public Database.QueryLocator start(Database.BatchableContext BC){
String query = 'Select Id, Amount from Opportunity where createdDate = This_Year';
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext BC, List<Opportunity> scope){
for(Opportunity opp : scope){
//The value of Summary will persist and added for all Opportunities in scope.
Summary = Opp.Amount+Summary;
}
}
public void finish(Database.BatchableContext BC){
}
}
Limitations of using Database.Stateful
There are a few disadvantages or limitations of using Database.Stateful that are listed below:
- Database.Stateful impacts the Batch performance by slowing it down.
- Batch class is serialized at the end of each execute method to update its internal state which results in longer execution time, if Database.Stateful is used.
- Static member variables don’t retain their values and are reset between transactions.
- “Internal Salesforce.com Error” is thrown on executing a stateful batch Apex job if Database.SaveResult stores the result of an operation with errors.
Alternatives to using Database.Stateful
While Database. Stateful is a useful way to maintain state or variable values, the same values can be stored in a custom setting or custom metadata to be retrieved in each transactions.
Conclusion
If your batch process needs information that is shared across transactions, one approach is to make the Batch Apex class itself stateful by implementing the Stateful interface. This instructs Force.com to preserve the values of your static and instance variables between transactions.