Batchable Apex and Schedulable Apex
* It is a powerful new feature to do batch processing on our database records.
* It was released in summer'09.
* It is used to execute large volumes of data unlike ordinary DML and SOQL statements.
* Tasks that require processing of
large data volumes without any active human intervention
can take advantage of this feature.
large data volumes without any active human intervention
can take advantage of this feature.
* As an example, consider the task of validating addresses in your contacts
when you can potentially have millions of contact records.
A batch job would be ideal for
this scenario since you can start the batch job,continue to work or even
log off while the job continues to execute.
when you can potentially have millions of contact records.
A batch job would be ideal for
this scenario since you can start the batch job,continue to work or even
log off while the job continues to execute.
* Batch-apex can execute large volumes of data up to 50 million records.
*To remove custom object records in bulk
we need to delete it through data loader,
now we can do it withBatch-apex.
we need to delete it through data loader,
now we can do it withBatch-apex.
*For Mass updating, inserting and
other similar scenarios like this can be more conveniently
handled with force.com's Batch Apex.
other similar scenarios like this can be more conveniently
handled with force.com's Batch Apex.
* With Batch Apex, we can now build complex, long-running processes on the platform.
This feature is very useful for time to time data cleansing, archiving
or data quality improvement operations.
This feature is very useful for time to time data cleansing, archiving
or data quality improvement operations.
* To use this functionality, you need to implement the Database.Batchable interface.
* 'Database' is a class and 'Batchable' is the interface inside the class.
* 'Database' is a class and 'Batchable' is the interface inside the class.
* This interface demands for three methods to be implemented:
1. Start()
2. execute()
3. finish()
***********
1. Start() Method:
* Start() method is called at the beginning of a batch Apex job.
* Use this method to collect the records (of objects) to
be passed to the "execute" method for processing.
be passed to the "execute" method for processing.
* The start() method determines the set of records that will
be processed by the executeBatch method. We would need
to construct a SOQL query and return a QueryLocator object.
be processed by the executeBatch method. We would need
to construct a SOQL query and return a QueryLocator object.
return
Database.getQueryLocator( 'SELECT Name, MailingAddress FROM Contact');
*QueryLocator can retrieve up to 50 million records at a time.
*Instead of QueryLocator, we can use 'Iterable' which can process
up to 50 thousand records.
* The Apex engine automatically breaks the massive numbers of records
we selected into smaller batches and
repeatedly calls the "execute" method until all records are processed.
* Start() and finish() methods executes only one time.
* But execute() method execute many times based on number of batches.
* We can perform all the DML operations here on bulk volumes of data.
*************
**************
Program to give 20% discount on all the books
****************************************
*Instead of QueryLocator, we can use 'Iterable' which can process
up to 50 thousand records.
* The Apex engine automatically breaks the massive numbers of records
we selected into smaller batches and
repeatedly calls the "execute" method until all records are processed.
* Start() and finish() methods executes only one time.
* But execute() method execute many times based on number of batches.
2. execute() Method:
* It will fetch the records from the start method.* We can perform all the DML operations here on bulk volumes of data.
3. finish() Method:
* All the post processing operations like sending emails will be done here.*************
Database.BatchableContext:
* It is the interface which holds the run-time information.**************
Program to give 20% discount on all the books
//To provide 20% discount for all the books
/*BatchApexProcessing b = new BatchApexProcessing();
Id jobid = Database.executeBatch(b,3);*/
//Note: If there are any triggers for the object which we are using for the
batchApexProcessing,
it won't work
//For the below class we are using list, so it can accept upto 50000 records
//Database is the class name and Batchable is the interface name which is inside
database class
//To access interface Database.Batchable we have to use
/*
global class BatchApexProcessing implements Database.Batchable<Book__c> {
global Iterable<Book__c> start(Database.BatchableContext bc){
List <Book__c> bl = new List <Book__c>();
bl = [select Id,Name,Author__c,Price__c from Book__c];
return bl;
}
global void execute(Database.BatchableContext bc, LIST<Book__c> bl) {
for(Book__c b:bl) {
b.Price__c *= 0.80;
}
update bl;
}
global void finish(Database.BatchableContext bc) {
}
}
*/
// ******** Using Query Locater ****************
//For the below class we are using Query Locater, so it can accept upto 50 million records
global class BatchApexProcessing implements Database.Batchable<sObject>,Database.stateful
{
//database.stateful is used to make data members with new values assigned should reflect
String myname = 'SRINU';
global Database.QueryLocator <Book__c> start(Database.BatchableContext bc) {
myname = 'SRINIVAS';
System.Debug('***** My Name in Start *****'+myname);
List <Book__c> bl = new List <Book__c>();
String Query = 'select Id,Name,Author__c,Price__c from Book__C';
return Database.getQueryLocator(Query);
}
global void execute(Database.BatchableContext bc, LIST<book__c> bl){
for(Book__c b:bl) {
System.Debug('***** My Name in Start *****'+myname);
b.Price__c *= 0.75;
}
update bl;
}
global void finish(Database.BatchableContext bc) {
System.Debug('***** My Name in Start *****'+myname);
}
}
****************************************
//Database is Class provided by Salesforce.
ReplyDelete//Batchable is an global interface which is inside of the Database class.
//Batchable include 3 method prototypes: 1. start 2. execute 3. finish
//start and finish methods will execute only one time.
//execute method executes multiple times.
global class BatchUsage implements Database.Batchable , Database.Stateful {
//at a time we can inherit multiple interfaces but we cannot inherit multiple classes.
//By default batch class is stateless (variable info. store in one method cannot be remembered in other method),
//to make it stateful we should inherit Database.Stateful interface.
String name = '';
global Database.queryLocator start(Database.BatchableContext bc) {
//From asynchronous to asynchronous we cannot call
//(from batch class we cannot call future mehthod vice versa.).
name += 'start';
system.debug('@@@Start Method: '+name);
//Collects the records to process. It will forward these records to execute method.
//If we use Iterable as return type for this start method it can hold
//max. of 50k records only.
//If we use Database.queryLocator as return type for this start method it can hold
//max. of 50 million records.
return Database.getQueryLocator('select id, name, Location__c from Department__c where Location__c = \'\'');
}
global void execute(Database.BatchableContext bc, LIST sObjLst) {
name += 'execute';
system.debug('@@@Execute Method: '+name);
//Split the records forwarded by start method into batches.
//Default batch size is: 200.
//Max. batch size is: 2000.
List depUPdLst = new List();
for(SObject sObj: sObjLst) {
Department__c dept = (Department__c) sObj;//Type Casting.
dept.Location__c = 'Bangalore';
depUPdLst.add(dept);
}
if(depUPdLst.size() > 0)
update depUPdLst;
}
global void finish(Database.BatchableContext bc) {
name += 'finish';
system.debug('@@@Finish Method: '+name);
//Post Commit logic like sending emails for the success or failures of the batches.
AsyncApexJob a = [select id, Status, NumberOfErrors, JobItemsProcessed,
TotalJobItems, CreatedBy.Email from AsyncApexJob where id =: bc.getJobId()];
Messaging.singleEmailMessage mail = new Messaging.singleEmailMessage();
mail.setToAddresses(new String[]{a.CreatedBy.Email});
mail.setSubject('Batch Class Result');
mail.setHtmlBody('The batch Apex job processed ' + '' + a.TotalJobItems + '' +
' batches with '+ '' + a.NumberOfErrors + '' + ' failures.');
//sendEmail methods
Messaging.sendEmail(new Messaging.singleEmailMessage[]{mail});
/*** Scheduling in minutes or hours ***/
/*//Create object for schedulable class
SchedulableUsage su = new SchedulableUsage();
//Preparing chron_exp
Datetime sysTime = System.now();
sysTime = sysTime.addminutes(6);
String chron_exp = '' + sysTime.second() + ' ' + sysTime.minute() + ' ' +
sysTime.hour() + ' ' + sysTime.day() + ' ' + sysTime.month() + ' ? ' + sysTime.year();
System.schedule('Dep Update'+sysTime.getTime(),chron_exp, su);*/
}
}