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