Database.Stateful in Batch Apex in Salesforce

Database.Stateful in Batch Apex in Salesforce


Each execution of a batch Apex job is considered a discrete transaction.


If we specify Database.Stateful in the class definition, we can maintain state across these transactions. Means we can track this variable status in start, execute and finish method. When using Database.Stateful, only instance member variables retain their values between transactions.  Static member variables don’t retain their values and are reset between transactions. If you don’t specify Database.Stateful, all static and instance member variables are set back to their original values.

Without Stateful:-

With out database.stateful the TotalOppAmount value will be reset to zero for every batch

With Stateful:-

With database.stateful the TotalOppAmount value will not reset for every batch execute method.

Use Case:- Suppose you want to track Total Amount of opportunity that’s created from Last Month. and According to business requirement these types of opportunity should be closed and need to share Total opportunity amount calculation by email.

For calculate Total Amount of opportunity we need to use interface Database.Stateful, that’s will maintain TotalOppAmount values from execute method to finish method.

public class Batch_Opportunity implements Database.Batchable<sObject>, Database.Stateful{

  public Decimal TotalOppAmount = 0.00;

   public Database.QueryLocator start(Database.BatchableContext BC){
      String query = '[SELECT ID, AMOUNT, STAGENAME FROM OPPORTUNITY WHERE CreatedDate >= Last_N_Months:1 AND STAGENAME != 'CLOSED' ]';
      return Database.getQueryLocator();
   public void execute(Database.BatchableContext BC,List<sObject> scope){
   List<OPPORTUNITY> oppList = new List<OPPORTUNITY>();
      for(sObject s : scope){
         TotalOppAmount = s.AMOUNT +Summary;
	  update oppList;

public void finish(Database.BatchableContext BC){

		AsyncApexJob job = [SELECT Id, Status, NumberOfErrors, JobItemsProcessed, TotalJobItems, CreatedBy.Email FROM AsyncApexJob  WHERE Id = :bc.getJobId()];
	// call some utility to send email

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();

        String[] toAddresses = new String[] {''};


        mail.setSubject('Batch Status ' + job.Status + 'Total OPPORTUNITY AMOUNT ' + TotalOppAmount );

        mail.setPlainTextBody('Total Jobs Processed: ' + job .TotalJobItems +   'with '+ job .NumberOfErrors + ' failures.');

        Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });



Leave a Reply