Google adds

Batch apex


Batch Apex
Batch Apex is used to run large jobs (think thousands or millions of records!) that would exceed normal processing limits. Using Batch Apex, you can process records asynchronously in batches (hence the name, “Batch Apex”) to stay within platform limits. If you have a lot of records to process, for example, data cleansing or archiving, Batch Apex is probably your best solution.
Here’s how Batch Apex works under the hood. Let’s say you want to process 1 million records using Batch Apex. The execution logic of the batch class is called once for each batch of records you are processing. Each time you invoke a batch class, the job is placed on the Apex job queue and is executed as a discrete transaction. This functionality has two awesome advantages:
  • Every transaction starts with a new set of governor limits, making it easier to ensure that your code stays within the governor execution limits.
  • If one batch fails to process successfully, all other successful batch transactions aren’t rolled back.



Batch Apex Syntax
Batch Apex class, your class must implement the Database.Batchable interface and include the following three methods:
start
Used to collect the records or objects to be passed to the interface method execute for processing. This method is called once at the beginning of a Batch Apex job and returns either a Database.QueryLocator object or an Iterable that contains the records or objects passed to the job.
With the QueryLocator object, the governor limit for the total number of records retrieved by SOQL queries is bypassed and you can query up to 50 million records. However, with an Iterable, the governor limit for the total number of records retrieved by SOQL queries is still enforced.
execute
Performs the actual processing for each chunk or “batch” of data passed to the method. The default batch size is 200 records. Batches of records are not guaranteed to execute in the order they are received from the start method.
This method takes the following:
·         A reference to the Database.BatchableContext object.
·         A list of sObjects, such as List<sObject>, or a list of parameterized types. If you are using a Database.QueryLocator, use the returned list.
finish
Used to execute post-processing operations (for example, sending an email) and is called once after all batches are processed.

global class MyBatchClass implements Database.Batchable<sObject> {
    global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {
        // collect the batches of records or objects to be passed to execute

   }
    global void execute(Database.BatchableContext bc, List<P> records){
        // process each batch of records
    }   
    global void finish(Database.BatchableContext bc){
        // execute any post-processing operations
    }   
}

Invoking a Batch Class
MyBatchClass myBatchObject = new MyBatchClass();
Id batchId = Database.executeBatch(myBatchObject);
APEX CODE:
global class LeadProcessor implements Database.Batchable <SObject> {
//START METHOD
    global Database.QueryLocator start(Database.BatchableContext bc){
        String Query='Select id,LeadSource from Lead';
        return Database.getQueryLocator(Query);
            }
//EXECUTE METHOD
    global void execute(Database.BatchableContext bc, List<Lead> scope){
        for(Lead l: scope){
            l.LeadSource='DreamForce';
        }
        update scope;
    }
//FINISH METHOD
    global void finish(Database.BatchableContext bc){
        Id job= bc.getJobId();
        System.debug(job);
    }
}
=======================================================================================================
TEST CLASS:
@istest
private class LeadProcessorTest {
    @istest
    static void tetslead(){
        List<Lead> l= new List<Lead>();
        lead l1= new Lead();
        l1.LastName='surya';
        l1.Company='Company';
        l1.Status='Closed-Converted';
        l1.LeadSource='Dreamforce';
        l.add(l1);
        insert l;
 
    Test.startTest();
    LeadProcessor lp= new LeadProcessor();
    Id jobid= Database.executeBatch(lp);
    Test.stopTest();
    }
}
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Batchable vs Future vs Queueable Apex in salesforce Explained
Batchable Apex :-
§  If it is a long running complex process then you should go for Batchable Apex and you can have an option to schedule the batch to run at customized time.
§  It can process upto 50 million records in asynchronous mode.
§  5 concurrent jobs are allowed to run at a time and future methods are not allowed in Batch class.
§  Batch Class should implement Database.Batchable interface and it should ave three methods start(), execute() and finish() methods.
Future Method :-
§  For avoiding Mixed_DML_Operations exception, we will be going for future method where it will be running in asynchronous mode when the system resource becomes available.
§  If you want to perform complex DML operations and want to make external webservice @future(callout=true) means you can go for future method.
§  Future method should be static and return type is void, parameters must be primitive types, sObjects are not accepted as future method parameters.
Queueable Apex :-             
§  It comes in handy , when you need to have both the operations of Batch and future method and it should implement Queueable Interface.
§  If one job is dependent on other job means here we can chain the dependent job in execute method by system.enqueuejob(new secondJob());
§  You can also able to chain upto 50 jobs and in developer edition you can able to chain upto 5 jobs only.
§  It will accept non-primitive types like sObjects and it also runs in asynchronous mode.
§  In this Queueable apex you can get Job Id to monitor the job progress.
-------------------------------------------------------------------------------------------------------------------------
Step 1: Write an apex class for Batch Apex.

Sample code:

global class AccountUpdate implements Database.batchable<sObject>
{

    String query,field,value;
   
    global AccountUpdate(String f, String v)
    {
        field = f;
        value = v;
        query = 'Select ' + field + ' FROM Account';
    }

    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        return Database.getQueryLocator(query);
    }
   
    global void execute(Database.BatchableContext BC, List<sObject> scope)
    {
         for(sobject s : scope)
         {
             s.put(Field,Value);
         }
         update scope;
    }
   
    global void finish(Database.BatchableContext BC)
    {
    }
   
}
--------------------------------------------------------------------------------------------------------------------------------
execute :

id jobid=database.executeBatch(new AccountUpdate('industry','banking'));

--------------------------------------------------------------------------------------------------------------------------------

How To Get Total Amount Of Records Processed In Batch Job In 10 Minutes And Still Look Your Best



Want count total amount of records which are processed in apex batch job?

Yeah, you can do it. Just implement Database.Stateful in your batch class and then you can have instance variables that don't lose state between batches.


Sample Code : 

global class implements Database.Batchable<sobject>, Database.stateful{

 public String query = 'Select id, Stage from Opportunity' ; 
 public Integer totalAmtOfRecords = 0; 

 global Database.QueryLocator start(Database.BatchableContext BC) {
    return Database.getQueryLocator(query);
 }

 global void execute(Database.BatchableContext BC, List<sobject> scope) {  
    totalAmtOfRecords += scope.size();
    //your logic ...
 }

 global void finish(Database.BatchableContext BC) {
    // Below line print Total amount of records processed in this Batch Job
    system.debug('Total amount of records processed :' + totalAmtOfRecords);  
 }

}


The totalAmtOfRecords stores only the initial state of the class. During execution of the batch job, yYou cannot use it to pass information between instances of the class. 
For example, if you change the value of totalAmtOfRecords in execute, the second chunk of processed records can’t access the new value. Only the initial value is accessible.

Below are the some important things you need to keep in mind while working on a batch class: 


1. Each execution of a batch Apex job is considered an individually separate transaction.
For example, a batch Apex job that contains 10,000 records and is executed without the optional scope parameter is considered fifty transactions of 200 records each.

2. If you specify Database.Stateful in the class, you can maintain state across these transactions. When using Database.Stateful, only instance member variables hold or retain their values between transactions. Static member variables do not hold their values & values are reset between transactions.

3. Maintaining state is useful for counting records as they’re processed.
For example, suppose your job processed opportunity records. You could define a sample method in execute function to perform logic like aggregate totals of the opportunity amounts as they were processed. You can use this count and send mail in final method to the users with job processed count and failure batch job count.

4. If you don’t implement Database.Stateful, all static and instance member variables are reset that is set back to their original values.

Always keep in mind that if your batch iteration seizes too large a number of records than you may still run into governing limits.

Below are the governor limits for Batch Apex:


  • Database.QueryLocator object returns a maximum of 50 million records in one transaction. If more than 50 million records are returned, the batch job is directly terminated or stop working and marked as Failed.
  • You can queue or active 1 to 5 batch jobs concurrently.
  • Apex flex queue holds up to 100 Holding batch jobs at a time.
  • You can submit a maximum of 5 batch jobs, in a running test.
  • Per 24-hour period, 250,000 of batch Apex method executions can be executed, or the number of user licenses in your org multiplied by 200—whichever is a greater number. Method executions contain executions of the start (), execute (), and finish () methods.
  • At a time, the batch Apex start () method can have up to 15 query cursors open per user. The batch Apex executes and finish methods each has a limit of 5 open query cursors per user.
  • If no size is specified with the optional scope parameter of Database.executeBatch, Salesforce divide the records returned by the start method into batches of 200 records. The system then passes each batch which of 200 records to the execute method. Apex governor limits are reset for each execution of execute () method.
  • Maximum 10 callouts can be implemented in the start, execute, and finish methods each.
  • Only one Apex batch job's start method can run at a time in an salesforce org. Apex Batch jobs that haven’t started yet remain in the queue until they are started. Note that if more than one job is running, this limit does not cause any batch job to terminate (fail) and execute methods of batch Apex jobs still run in parallel.

Refrence : https://www.linkedin.com/pulse/salesforce-batch-apex-ankur-garg

No comments:

Post a Comment

All Governor Limit

Number of SOQL queries: 100 Number of query rows: 50,000 Number of SOSL queries: 20 Number of DML statements: 150 Number of DML rows: 10,...