Database.Stateful. When to use it?

  • I am writing a batch class which will get the records whose status picklist value is 'no response' and whose created date is before greater than or equal to 48 hrs and update the status to 'declined'.

    Do I need to use Database.stateful here ?

    global class SolicitaBatch implements Database.Batchable<sObject>{
    String query;
    String email;
    Id toUserId;
    Id fromUserId;
    
    global Database.QueryLocator start(Database.BatchableContext BC)
        {
            Datetime dtime = datetime.now().addhours(-48);
            String query = 'select id,createdDate, Status__c from Solicitation__C  where createdDate <= :dtime and Status__c = \'No Response\' ';
            return Database.getQueryLocator(query);
        }
    
    global void execute(Database.BatchableContext BC, List<Solicitation__C> scope){
        List<Solicitation__C> Sols = new List<Solicitation__C>();
        for(Solicitation__C s : scope)
        {
            s.Status__c = 'ABCD';
        }
        update scope;
    
    } 
    
    global void finish(Database.BatchableContext BC)
        {
            Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
    
            mail.setToAddresses(new String[] {email});
            mail.setReplyTo('[email protected]');
            mail.setSenderDisplayName('Batch Processing');
            mail.setSubject('Batch Process Completed');
            mail.setPlainTextBody('Batch Process has completed');
    
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail });
        }
    }
    
  • sfdcfox

    sfdcfox Correct answer

    4 years ago

    The only time you need Database.Stateful is when the execute method modifies a class variable in a way meant to be used across multiple execute methods or in the finish method. The majority of batches you will ever write will not need Database.Stateful. It's important to know that using Database.Stateful will harm your batch's performance, because 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.

    If you're ever not sure if you need it, simply ask yourself two questions: (1) "Does one execute method need data from a previous execute method?", and (2) "Does the finish method need data from any previous execute method?" If the answer to both of these questions is no, then you do not need Database.Stateful. If the answer is yes, then you may want to use Database.Stateful. Keep in mind that there are alternative means to using Database.Stateful, such as storing data in a Custom Setting, which may offer better performance in some cases.

    Can you please share other alternative ways besides writing data into custom setting, If there are any?

    @javanoob Anything you can persist to the database would work. I've used a Document, for example, as well custom objects (e.g. a logging object). In theory, you could also use the platform cache, but I consider it too unreliable for that purpose, since it can be purged at any time by the system to make room for new data. Hitting the database for the same Document over and again each transaction is just about as fast as a Custom Setting, but does use a query to get the data back.

License under CC-BY-SA with attribution


Content dated before 7/24/2021 11:53 AM

Tags used