Thursday 25 February 2016

Batch Apex in salesforce | Test class for Batch job | how to schedule batch job


Batch Apex
A Batch class allows you to define a single job that can be broken up into manageable chunks that will be processed separately.


When to use Batch Apex

One example is if you need to make a field update to every Account in your organization. If you have 10,001 Account records in your org, this is impossible without some way of breaking it up. So in the start() method, you define the query you're going to use in this batch context: 'select Id from Account'. Then the execute() method runs, but only receives a relatively short list of records (default 200). Within the execute(), everything runs in its own transactional context, which means almost all of the governor limits only apply to that block. Thus each time execute() is run, you are allowed 150 queries and 50,000 DML rows and so on. When that execute() is complete, a new one is instantiated with the next group of 200 Accounts, with a brand new set of governor limits. Finally the finish() method wraps up any loose ends as necessary, like sending a status email.


Sample Batch Apex

1) Start method is automatically called at the beginning of the apex job. This method will collect record or objects on which the operation should be performed. These record are divided into subtasks & passes those to execute method.

2) Execute Method performs operation which we want to perform on the records fetched from start method.

3) Finish method executes after all batches are processed. Use this method to send confirmation email notifications.



global class AccountUpdateBatchJob implements Database.Batchable<sObject>
{
    global Database.QueryLocator start(Database.BatchableContext BC)
    {
        String query = 'SELECT Id,Name FROM Account';
       
        return Database.getQueryLocator(query);
    }
    global void execute(Database.BatchableContext BC, List<Account> scope)
    {
        for(Account a : scope)
        {
            a.Name = a.Name + 'Updated by Batch job';
        }
        update scope;
    }
    global void finish(Database.BatchableContext BC) {
    }
}




Calling on Batch Apex

            AccountUpdateBatchJob obj = new AccountUpdateBatchJob();
            DataBase.executeBatch(obj);




Scheduler Class For Batch Apex


global class AccountUpdateBatchJobscheduled implements Schedulable 
{
    global void execute(SchedulableContext sc) 
    {
        AccountUpdateBatchJob b = new AccountUpdateBatchJob(); 
        database.executebatch(b);
    }
}
Please check below post for scheduler test class

URL :- http://amitsalesforce.blogspot.in/2017/07/how-to-write-test-class-for-scheduler.html



How to Schedule scheduler class

There are two option we have schedule the scheduler classes.
1) By System Scheduler.
2) By Developer console

System Scheduler.

Step 1) Click on Setup->Apex class. Then search Schedule Apex button.

Step 2) Select the scheduler class and set Time like below screen shot.




By Developer console 

Execute below code from developer console :-

AccountUpdateBatchJobscheduled m = new AccountUpdateBatchJobscheduled();
String sch = '20 30 8 10 2 ?';
String jobID = system.schedule('Merge Job', sch, m);



Test Class


@isTest
public class AccountUpdateBatchJobTest
{
    static testMethod void testMethod1()
    {
        List<Account> lstAccount= new List<Account>();
        for(Integer i=0 ;i <200;i++)
        {
            Account acc = new Account();
            acc.Name ='Name'+i;
            lstLead.add(acc);
        }
       
        insert lstAccount;
       
        Test.startTest();

            AccountUpdateBatchJob obj = new AccountUpdateBatchJob();
            DataBase.executeBatch(obj);
           
        Test.stopTest();
    }
}


Limits in Batch Apex

1) Up to five queued or active batch jobs are allowed for Apex
2) Cursor limits for different Force.com features are tracked separately. For example, you can have 50 Apex query cursors, 50 batch cursors, and 50 Visualforce cursors open at the same time.
3) A maximum of 50 million records can be returned in the Database.QueryLocator object. If more than 50 million records are returned, the batch job is immediately terminated and marked as Failed
4) If the start method returns a QueryLocator, the optional scope parameter of Database.executeBatch can have a maximum value of 2,000. If set to a higher value, Salesforce chunks the records returned by the QueryLocator into smaller batches of up to 2,000 records. If the start method returns an iterable, the scope parameter value has no upper limit; however, if you use a very high number, you may run into other limits.
5) If no size is specified with the optional scope parameter of Database.executeBatch, Salesforce chunks the records returned by the start method into batches of 200, and then passes each batch to the execute method.Apex governor limits are reset for each execution of execute.
6) The start, execute, and finish methods can implement up to 10 callouts each
7) The maximum number of batch executions is 250,000 per 24 hours
8) Only one batch Apex job's start method can run at a time in an organization. Batch jobs that haven’t started yet remain in the queue until they're started. Note that this limit doesn’t cause any batch job to fail and execute methods of batch Apex jobs still run in parallel if more than one job is running


Some Useful link :-

https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_batch_interface.htm
https://developer.salesforce.com/docs/atlas.en-us.apex_workbook.meta/apex_workbook/apex_batch_intro.htm


3 comments:

  1. Hi Amit,

    I have an issue that my test method for batch class does not invoke the execute part of batch. Test class is working only in 75% coverage.
    Can you help me to solve the problem?
    I think that it is not a limits problem, but something else.

    ReplyDelete
  2. Hi Amit,

    Thanks for sharing the knowledge , but i wanted to know one thing that i want output of 1st batch job which will be input for another batch job so basically its batch chaining. how to do that I have in my mind to declare variable in 1st batch job but stuck how to traverse to 2nd batch job? Kindly help!

    ReplyDelete
  3. Hi i have an issue while executing the batch class, if you could help in resolving this

    ReplyDelete