Database.Stateful in Batch Apex Class
Sateful and Stateless Batch Apex :
In Batch Apex, the Stateful and stateless terms refer to whether or not the batch job maintains its state between executions of the execute() method.
A stateful batch job is one in which the state of the batch job is maintained between executions of the execute() method. This means that the batch job can keep track of information, such as the number of records processed, between executions of the execute() method. This allows you to implement more complex logic, such as maintaining a running total of the number of records processed.
On the other hand, a stateless batch job is one in which the state of the batch job is not maintained between executions of the execute() method. This means that the batch job does not keep track of information between executions of the execute() method, and it must rely on other means of storing state, such as a separate object or a class variable.
The choice between stateful and stateless depends on the requirements of the job, stateful job are better suited for keeping track of a running total, or maintaining other state information across multiple executions of the execute() method, but it can also lead to performance degradation as it will hold state in memory. While stateless jobs are better suited for cases where state does not need to be maintained between executions, which can lead to a better memory management and performance.
In summary, Stateful Batch Apex code will maintain state across multiple execution of the batch job and Stateless Batch Apex code will not maintain state across multiple execution of the batch job.
Here we will understand the meaning of stateful using batch apex example:
global class ContactUpdateBatch implements Database.Batchable<sObject>, Database.Stateful {
??global final String query;
??global Integer recordsProcessed = 0;
???
??global ContactUpdateBatch(String q) {
????query = q;
??}
???
??global Database.QueryLocator start(Database.BatchableContext bc) {
????return Database.getQueryLocator(query);
??}
???
??global void execute(Database.BatchableContext bc, List<sObject> scope) {
????List<Contact> contactsToUpdate = (List<Contact>)scope;
????for (Contact c : contactsToUpdate) {
??????c.Title = 'Mr.';
??????recordsProcessed = recordsProcessed + 1;
????}
????update contactsToUpdate;
??}
???
??global void finish(Database.BatchableContext bc) {
????// Send an email with the number of records processed
????Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
????email.setToAddresses(new String[] {'[email protected]'});
????email.setSubject('Contact Update Batch Job Results');
????email.setPlainTextBody('The batch job updated ' + recordsProcessed + ' contact records.');
????Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});
??}
}
In this example, the ContactUpdateBatch class implements the Database.Batchable and Database.Stateful interfaces, and defines the three methods required by the interface: start(), execute(), and finish().
The start() method takes a Database.BatchableContext parameter, it retrieves the contacts that will be updated using the query passed in the constructor and returns a Database.QueryLocator object.
The execute() method takes two parameters, the Database.BatchableContext and a list of sObjects, it then cast the sObject list to List<Contact> and then updates the Title field to 'Mr.' and increases the recordsProcessed variable.
The finish() method takes a Database.BatchableContext parameter, and it's responsible for sending an email with the number of records processed, stored in the recordsProcessed variable.
You can run this Batch Apex class in the execute anonymous window of the developer console by using this line of code:
Id batchId = Database.executeBatch(new ContactUpdateBatch('SELECT Id, Title FROM Contact'), 200);
This will create a new instance of the ContactUpdateBatch class and pass a query to retrieve all the contact records, and also specifying the batch size of 200.