Batch Apex is stateless. Each execution of a
batch Apex job is considered a discrete transaction. If we implement a
Database.Stateful, we can maintain state across transactions. Using
Database.Stateful only instance variables hold values; static members do not
hold values. If we want to count records as a batch proceeds, maintaining state
is important, as after one transaction, a new transaction will start and
members will lose their values.
Let's understand with an example,
The below batch class is querying all the accounts and their related contacts and updating the contact phone number with the account phone number. As we want to count the number of contacts updated using the batch class, we are implementing a Database.Stateful interface and finally sending mail to inform the user regarding the batch status.
public
class UpdateContactPhone implements
Database.Batchable<sObject>,
Database.Stateful {
public Integer recordsProcessed = 0;
public Database.QueryLocator start(Database.BatchableContext
bc) {
String query = 'SELECT
Id,Name,Phone,(SELECT id,Phone from Contacts) FROM Account';
return Database.getQueryLocator(query);
}
public void execute(Database.BatchableContext
bc, List<Account> scope){
// process each batch of records
List<Contact> contacts = new
List<Contact>();
for (Account account : scope) {
for (Contact contact :
account.contacts) {
contact.phone= account.phone;
contacts.add(contact);
recordsProcessed =
recordsProcessed + 1;
}
}
update contacts;
}
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[]
{'Testabc@gmail.com'};
mail.setToAddresses(toAddresses);
mail.setSubject('Batch Status ' +
job.Status + 'Record Processed ' + recordsProcessed );
mail.setPlainTextBody('Total Jobs
Processed: ' + job .TotalJobItems +
'with '+ job .NumberOfErrors + ' failures.');
Messaging.sendEmail(new Messaging.SingleEmailMessage[]
{ mail });
}
}
It is very awesome point of explanation with code example.
ReplyDelete