Batch Apex is stateless. Each execution of a batch Apex job is considered a discrete transaction. If we implements Database.Stateful we can maintained state across transactions. Using Database.Stateful only instance variable holds values static members does not hold values. If we want to count records as batch proceeds maintaining state is important as after one transaction new transaction will start and members will loose their values.
Let's understand with an example,
public class
UpdateContactAddresses 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