Batch Apex Similified

In order to process the large number of records, we use batch apex in salesforce.

I hope you already know how to write a batch and how to use it. So I am giving you just few examples and important points to be considered while using the batch –

Refer this for Iterable example.

Using Database.QueryLocator to Define Scope

The start method can return either a Database.QueryLocator object that contains the records to use in the batch job or an iterable.

The following example uses a Database.QueryLocator:

1.       public class SearchAndReplace implements Database.Batchable{

2.        

3.          public final String Query;

4.          public final String Entity;

5.          public final String Field;

6.          public final String Value;

7.        

8.          public SearchAndReplace(String q, String e, String f, String v){

9.        

10.          Query=q; Entity=e; Field=f;Value=v;

11.       }

12.     

13.       public Database.QueryLocator start(Database.BatchableContext BC){

14.          return Database.getQueryLocator(query);

15.       }

16.     

17.       public void execute(Database.BatchableContext BC, List scope){

18.         for(sobject s : scope){

19.         s.put(Field,Value);

20.         }

21.         update scope;

22.        }

23.     

24.       public void finish(Database.BatchableContext BC){

25.       }

26.    }

 

Important points:

 
1.        If you use a QueryLocator object, the governor limit for the total number of records retrieved by SOQL queries is bypassed. 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.
 
2.       If you use an iterable, the governor limit for the total number of records retrieved by SOQL queries is still enforced.
 
3.       Batches of records tend to execute in the order in which they’re received from the start method. However, the order in which batches of records execute depends on various factors. The order of execution isn’t guaranteed.
 
4.       Each execution of a batch Apex job is considered a discrete transaction. For example, a batch Apex job that contains 1,000 records and is executed without the optional scope parameter from Database.executeBatch is considered five transactions of 200 records each. The Apex governor limits are reset for each transaction. If the first transaction succeeds but the second fails, the database updates made in the first transaction are not rolled back.
 
5.       If the start method of the batch class 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 of the batch class returns an iterable, the scope parameter value has no upper limit. However, if you use a high number, you can run into other limits.
 
6.       The Database.executeBatch method returns the ID of the AsyncApexJob object, which you can use to track the progress of the job. For example:
ID batchprocessid = Database.executeBatch(reassign);
AsyncApexJob aaj = [SELECT Id, Status, JobItemsProcessed, TotalJobItems, NumberOfErrors FROM AsyncApexJob WHERE ID =: batchprocessid ];
while the System.scheduleBatch method returns the scheduled job ID (CronTrigger ID). For example:
String cronID = System.scheduleBatch(reassign, 'job example', 1);
CronTrigger ct = [SELECT Id, TimesTriggered, NextFireTime FROM CronTrigger WHERE Id = :cronID];
// TimesTriggered should be 0 because the job hasn't started yet.
System.assertEquals(0, ct.TimesTriggered);
System.debug('Next fire time: ' + ct.NextFireTime);
 
7.       The scheduler runs as system — all classes are executed, whether or not the user has permission to execute the class.
 
8.       All scheduled Apex limits apply for batch jobs scheduled using System.scheduleBatch. After the batch job is queued (with a status of Holding or Queued), all batch job limits apply and the job no longer counts toward scheduled Apex limits
 
9.       While submitted jobs have a status of Holding, you can reorder them in the Salesforce user interface to control which batch jobs are processed first. To do so, from Setup, enter Apex Flex Queue in the Quick Find box, then select Apex Flex Queue.
Alternatively, you can use Apex methods to reorder batch jobs in the flex queue. To move a job to a new position, call one of the System.FlexQueue methods. Pass the method the job ID and, if applicable, the ID of the job next to the moved job’s new position. For example:
Boolean isSuccess = System.FlexQueue.moveBeforeJob(jobToMoveId, jobInQueueId);
 
10.  To use a callout in batch Apex, specify Database.AllowsCallouts in the class definition. For example:
public class SearchAndReplace implements Database.Batchable, Database.AllowsCallouts{
}
 
11.  The start, execute, and finish methods can implement up to 100 callouts each.
 
12.  If you specify Database.Stateful in the class definition, you can maintain state across these transactions. When using Database.Stateful, only instance member variables retain their values between transactions. Static member variables don’t retain their values and are reset between transactions. Maintaining state is useful for counting or summarizing records as they’re processed. For example, suppose your job processed opportunity records. You could define a method in execute to aggregate totals of the opportunity amounts as they were processed.
 
13.  With the Apex flex queue, you can submit up to 100 batch jobs. If the Apex flex queue has the maximum number of 100 jobs, Database.executeBatch throws a LimitException and doesn’t add the job to the queue.
 
14.  Up to 5 batch jobs can be queued or active concurrently.
 
15.  Only one batch Apex job's start method can run at a time in an org.
 
16.  In a running test, you can submit a maximum of 5 batch jobs.
 
17.  If your org doesn’t have Apex flex queue enabled, Database.executeBatch adds the batch job to the batch job queue with the Queued status. If the concurrent limit of queued or active batch job has been reached, a LimitException is thrown, and the job isn’t queued.
 
18.  The maximum number of batch Apex method executions per 24-hour period is 250,000, or the number of user licenses in your org multiplied by 200—whichever is greater. Method executions include executions of the start, execute, and finish methods. This limit is for your entire org and is shared with all asynchronous Apex: Batch Apex, Queueable Apex, scheduled Apex, and future methods. To check how many asynchronous Apex executions are available, make a request to REST API limits resource. See List Organization Limits in the REST API Developer Guide. The licenses that count toward this limit are full Salesforce user licenses or App Subscription user licenses. Chatter Free, Chatter customer users, Customer Portal User, and partner portal User licenses aren’t included.
 
19.  The executeBatch method starts an asynchronous process. When you test batch Apex, make certain that the asynchronously processed batch job is finished before testing against the results. Use the Test methods startTest and stopTest around the executeBatch method to ensure that it finishes before continuing your test.
 
20.  Future methods can’t be called from a batch Apex class.
 
21.  When a batch Apex job is run, email notifications are sent to the user who submitted the batch job. If the code is included in a managed package and the subscribing org is running the batch job, notifications are sent to the recipient listed in the Apex Exception Notification Recipient field.
 
22.  Each batch Apex invocation creates an AsyncApexJob record. To construct a SOQL query to retrieve the job’s status, number of errors, progress, and submitter, use the AsyncApexJob record’s ID. For more information about the AsyncApexJob object, see AsyncApexJob in the Object Reference for Salesforce. For each 10,000 AsyncApexJob records, Apex creates an AsyncApexJob record of type BatchApexWorker for internal use. When querying for all AsyncApexJob records, we recommend that you filter out records of type BatchApexWorker using the JobType field. Otherwise, the query returns one more record for every 10,000 AsyncApexJob records.
 
23.  For a sharing recalculation, Its recommended that the execute method delete and then re-create all Apex managed sharing for the records in the batch. This process ensures that sharing is accurate and complete.
 
24.  Ensure that batch jobs execute as fast as possible. To ensure fast execution of batch jobs, minimize Web service callout times and tune queries used in your batch Apex code. The longer the batch job executes, the more likely other queued jobs are delayed when many jobs are in the queue.
 
25.  Batch Apex jobs run faster when the start method returns a QueryLocator object that doesn't include related records via a subquery. Avoiding relationship subqueries in a QueryLocator allows batch jobs to run using a faster, chunked implementation. If the start method returns an iterable or a QueryLocator object with a relationship subquery, the batch job uses a slower, non-chunking, implementation. For example, if the following query is used in the QueryLocator, the batch job uses a slower implementation because of the relationship subquery:
SELECT Id, (SELECT id FROM Contacts) FROM Account
A better strategy is to perform the subquery separately, from within the execute method, which allows the batch job to run using the faster, chunking implementation.
 
26.  Starting with API version 26.0, you can start another batch job from an existing batch job to chain jobs together. Chain a batch job to start a job after another one finishes and when your job requires batch processing, such as when processing large data volumes. Otherwise, if batch processing isn’t needed, consider using Queueable Apex.

Published by Sandeep Kumar

He is a Salesforce Certified Application Architect having 11+ years of experience in Salesforce.

Leave a Reply