anusha(salesforce developer)

Friday, 10 June 2016

BATCH APEX

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.
*  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.
* 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.
*For Mass updating, inserting and 
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.
* To use this functionality, you need to implement the Database.Batchable interface.
'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. 
* 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.
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.

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);
    }   
}

 
 ****************************************

1 comment:

  1. //Database is Class provided by Salesforce.
    //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);*/
    }
    }

    ReplyDelete