Know when the last batch job in parallel execution finishes

apexasynchronousbatch

I have an apex class that is executed in parallel by calling Database.executeBatch() in a loop, where each instance processes a chunk of a dataset.

After all the jobs that were executed finish I need to execute some apex.

My initial thought is to query the AsyncApexJob records in the finish method of each batch instance, then kick off the final apex when no other jobs exist.

I'm worried there's an edge case with the last 2 jobs calling finish at the same time and not calling the final apex action.

Is there a better way to know when all submitted jobs have finished?

Best Answer

I'm thinking I can use the Org cache to put how many instances of the job were executed, then in the finish method I can create a platform event that invokes a trigger to update the number of jobs executing.

When that cache value reaches 0 in the trigger, I can execute the apex

Edit: This still isn't a 100% perfect solution because the trigger subscribed to the platform event could run in parallel and the platform cache does not have mutexes for reading/writing.

Instead of using the platform cache I may need to use a concrete object using FOR UPDATE to have a platform level mutex on the record to update the # of parallel jobs in a thread safe manner

Related Topic