Start: This method is called at the starting of a batch job to collect the data on which the batch job will be operating. It breaks the data or record into batches.
Execute: This method executes after the Start method, and it does the actual processing for each batch, separately.
global void execute(Database.BatchableContext BC, list<sobject>) {}
Finish: This method will be called at last. Since this method is called in the end, it is responsible to perform post-processing operations such as sending an email. When this process is called all batches are already executed.
global void finish(Database.BatchableContext BC) {}
Database.executeBatch(new BatchApexExample(),100);
To monitor or stop the execution of the batch Apex job, from Setup, enter Apex Jobs in the Quick Find box, then select Apex Jobs.
At maximum, only 5 Batch jobs can be chained to one another.
global database.querylocator start(Database.BatchableContext BC)
{
//start method logic here
}
global void execute(Database.BatchableContext BC, List<sObject> scope)
{
//start method logic here
}
global void finish(Database.BatchableContext BC)
{
//Batch Chaining Step Starts here
AccountBatch accBatch = new AccountBatch ();
Id batchProcessId = Database.executeBatch(accBatch);
//finish method logic here
}
It is Database.Batchable interface.
There are various reasons why Batch Apex is better than normal Apex:
Salesforce by default allows 5 active batches running at a time and other batches will be in queue for running.
Agree with this point if and only if the data needs to be updated is static or predefined or which can be done through excel.
We will choose batch class if we have to perform some custom calculations at run time or if you want to run some complex logic which can’t be driven by excel sheets. In those cases, we have to go with batch classes.
Examples:
It depends on your batch size what you have configured at the time of calling the batch class from schedule class.
Execution method count = Total No Of Records / Batch Size (Any decimal ceil it to upper value)
If you haven’t set any batch size then – 1234/200 = 6.17 = 7 times execute method will be called.
2000
1
200
At a time Salesforce allows 5 batches to be running or to be in queued state. So, if you have consumed all these 5 limits and if the system has received one or more batch execution requests, all these waiting batches will be stored in this Apex Flex Queue.
100
It is because the execute method gets invoked multiple times based on the volume of the records and batch size. So, if you’re calling it from the execute method then the chaining class will get called multiple times which is not a suggested way of doing it.
With a 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.
Batch Apex is typically stateless. Each execution of a batch Apex job is considered a discrete transaction. For example, a batch Apex job that contains 1,000 records and uses the default batch size is considered five transactions of 200 records each.
If you specify Database.Stateful in the class definition, you can maintain state across all transactions. When using Database.Stateful, only instance member variables retain their values between transactions. Maintaining state is useful for counting or summarizing records as they’re processed.
You should only use Batch Apex if you have more than one batch of records. If you don’t have enough records to run more than one batch, you should use Queueable Apex.
To use HTTP Callouts in a batch class we need to use Database.AllowsCallouts in the interface.
If any record fails and uses standard DML, all 200 records will fail, but the next batch will get executed.
Yes, we can call from the finish method.
Only in the batch class finish method can we call another batch class. If you call another batch class from the batch class execute and start method, Salesforce will throw the below runtime error:
System.AsyncException: Database.executeBatch cannot be called from a batch start, batch execute, or future method.
Yes, it is possible. We can call a batch apex from a trigger but we should always keep in mind that we should not call batch apex from a trigger each time as this will exceed governor limits due to the constraint that we can only have 5 apex jobs queued or executing at a time.
Start method and finish method execute one time each. The execute method depends on requirements, based on the batch size and data retrieved in the Start method.
No, we can’t call it directly from execute/start.
Yes, but you’re limited to just one System.enqueueJob call per execute in the Database.Batchable class. Salesforce has imposed this limitation to prevent explosive execution.
Code is run between Test.startTest and Test.stopTest. Any asynchronous code included within Test.startTest and Test.stopTest is executed synchronously after Test.stopTest.
We have to make sure that the number of records inserted is less than or equal to the batch size of 200 because test methods can execute only one batch. We must also ensure that the Iterable returned by the start method matches the batch size.
The Apex Flex queue enables you to submit up to 100 batch jobs for execution. Any jobs that are submitted for execution are in holding status and are placed in the Apex Flex queue.
Jobs are processed first-in first-out. You can look at the current queue order and shuffle the queue to move an important job to the front:
Boolean isSuccess = System.FlexQueue.moveBeforeJob(jobToMoveId, jobInQueueId);
Once you run Database.executeBatch, jobs are placed in the Apex flex queue. Since the Flex queue has a maximum limit of 100 jobs, throwing a LimitException occurs if exceeded. Furthermore, concurrent active execution is limited to 5.
No, we can’t. It will throw an exception stating that “Locking is implied for each batch execution and therefore FOR UPDATE should not be specified”.
Yes, you can do subqueries for related records, but with a relationship subquery, batch job processing becomes slower. A better strategy is to perform the subquery separately from within the execute method.
global class batchExample implements Database.Batchable<sObject> {
global (Database.QueryLocator | Iterable<sObject>) start(Database.BatchableContext bc) {
// collect batches of records
}
global void execute(Database.BatchableContext bc, List<sObject> records){
// process each batch
}
global void finish(Database.BatchableContext bc){
// post-processing
}
}
In batches, failures are scoped to the batch transaction. The first batch (records 1–200) succeeds and commits. If the second batch encounters an unhandled exception, that batch (records 201–400) rolls back.
The Database.executeBatch and System.scheduleBatch methods return an ID that can be used in the System.abortJob method.
Methods declared as future can’t be called directly from a Batch Apex execute/start method.
Aggregate queries don’t work natively in Batch QueryLocators because they don’t support queryMore(), throwing errors. Use Iterables or standard SOQL loops instead.
Database.Batchable: An interface acting as a blueprint telling Salesforce your class is ready for batch processing.
Database.BatchableContext: A context variable storing runtime information about the batch job, like the job ID.
It won't let you save the class as it violates the Database.Batchable interface contract.
Calling a future method directly is not allowed in the Execute method, but web services or Queueable Apex can act as intermediaries.
It stores runtime information such as the Job ID and gives context to the batch execution methods.
Yes, you can write helper methods, but only start, execute, and finish are defined by the Database.Batchable interface.
Global makes a class usable by code outside of its defining namespace or managed package.
Standard DML (insert) rolls back or throws exceptions on bulk errors, whereas Database methods allow partial processing using allOrNone settings.
Database.insert handles DML behavior per transaction, while Database.Stateful maintains member variable states across distinct batch transactions.
The finish method is synchronous; it runs immediately after the last execute transaction finishes without entering an execution queue.
1. Use Database.AllowsCallouts interface at the class level.
2. Perform callouts inside the execute method.
Callouts are not supported in the start method because it breaks query locator processing rules and hits governor limits.
Yes, queueables can be called from the finish method of a batch.
Yes, you can chain them from the finish method.
Yes, by using an Iterable implementation to pass pre-collected collections or objects.
Annotate a static void method with @future. Parameters must be primitive data types or collections of primitives.
Primitives are immutable and simple, ensuring data integrity doesn't break between the time of method queueing and asynchronous execution.
ClassName.methodName();
1. Background execution.
2. Mixed DML isolation (Setup and Non-setup objects).
3. Performing callouts from triggers.
1. Cannot call another future method.
2. Only accepts primitive data types/collections.
3. Order of execution is not guaranteed.
global class FutureClass {
@future
public static void myFutureMethod() {
// Perform operations
}
}
Pass a collection of sObject IDs instead of the sObject instances, then query fresh records inside the future method.
Add the callout parameter to the annotation:
@future(callout=true)
public static void doCallouts(String name) {
// Perform callout
}