-1

I've recently implemented a class with Batchable in apex. There has been multiple issues, but the biggest is the finish method being invoked after every batch. I have tested by sending email from the finish method every time it's invoked. This is done in a developer console.

The batch class is supposed to process 1000 records, where one batch should handle 1000 records (this has been specified). When executing, I get 7 emails from the finish method, meaning it goes in to the finish method 7 times.

With further examination it showed the batch class splitting the data in to 200 records per batch, and invoking the finish method in every batch, not waiting until everything was done.

The class implements Database.Batchable and Database.Stateful. I don't know whether Database.Stateful affects it in some way.

Does anyone know why this happens?

2
  • How is the batch getting called? Is it from a Trigger? Commented Jul 21, 2022 at 13:56
  • It is indeed from a trigger, After Insert.
    – Nonya
    Commented Jul 21, 2022 at 13:59

2 Answers 2

6

Salesforce batch class is designed in a way that start(Database.BatchableContext bc) and finish(Database.BatchableContext BC) runs only once in the entire context of batch class run. It is the execute(Database.BatchableContext BC, list<sObject>) which runs multiple times based on batch size and total number of records returned from start method and each run of the execute method has it's own order of execution and gets reset after every run.

For example: when a batch runs let suppose the batch size is 300 and total number of records returned from start method is 700.

So number of times execute method will run = 700/ 300 = 2.33 = 3 times (Rounded of to next high value, since batch cannot run in decimal context i.e either batch is processing all values corresponds to batch size or processing records less than < batch size)

so 1st execute method run(it completes one full salesforce order of execution )--->2nd execute start ( it completes one full salesforce order of execution which is not linked to 1st batch execution) ---> similarly 3rd execute runs

If your email is getting sent from finish method, there is no way it will fire multiple times in a single batch run context.

From the comment we can conclude since the batch is getting fired from trigger and trigger runs on batch of 200 records (Please refer documentation for more information)

Beyond the Basics Triggers execute on batches of 200 records at a time. So if 400 records cause a trigger to fire, the trigger fires twice, once for each 200 records. For this reason, you don’t get the benefit of SOQL for loop record batching in triggers, because triggers batch up records as well. The SOQL for loop is called twice in this example, but a standalone SOQL query would also be called twice. However, the SOQL for loop still looks more elegant than iterating over a collection variable!

Therefore batch's finish method is getting triggered multiple times and hence you are receiving multiple emails

1

As mentioned in the comment you are calling the Batch class from AfterInsert context in trigger.

When there are more than 200 records trigger processes in chunks of 200 records and so your batch is executing multiple times and you are getting more number of emails .

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .