Recently , I inherited an Org with huge customization , which enqueue 100+ Batch Jobs in few scenario. Now, don’t ask me why ?
I remember, few years back, Salesforce had limit of 5 Apex Batch that can be executed at a time, but we had expectation and demand !!! Salesforce introduced Flex queue and we can have 100 Batch apex waiting to be executed, still we are not happy. After all, human is wanting animal.
After 100 Batch apex, all jobs were failing with error System.AsyncException You have exceeded the limit of 100 Jobs in the flex queue. As I explained my life previously in this post, I had to fix this issue as well.
Right way to fix it was to analyze existing code, perform code review, why do we need even customization etc.. However, time was crucial and I had to do something quickly.
Below framework was used to fix the issue
- Create a Custom Object to hold information about batch
- Use an intermediate Apex class to queue Batch Apex and Queueable Apex. If there is no availability in Flex queue then simply dump it in custom object.
- Use a Scheduler which will run every 10 mins, check Flex queue and submit batches from Custom object if limit available
As you can see in below code, syntax to submit batch Apex is almost similar.
Instead of
ID batchprocessid = Database.executeBatch(batchApexInstance,200);
we would be using
ID batchprocessid = AsyncApexFramework.submitBatch(batchApexInstance,batchSize,Prioity,isRetry);
AsyncApexFramework.flush();
Where ,
- @Param 1 – Instance of Batch Apex
- @Param 2 – Batch Size / Scope Size
- @Param 3 – Priority to process if there are many job in Queue. If null then default would be 99
- @Param 4 – if Batch Apex has error, should it be retried again ? Use this option carefully , make sure your design does not negatively impact if same Batch runs multiple time
Same way , instead of using
Id jobId = System.enqueueJob(queueableClassInstance)
We would be using
Id jobId = AsyncApexFramework.submitQueueable(queueableClassInstance,priority,isRetry);
AsyncApexFramework.flush();
Where,
- @Param 1 – Instance of Queueable class
- @Param 2 – Priority to process if there are many job in Queue. If null then default would be 99
@Param 3 – if Batch Apex has error, should it be retried again ? Use this option carefully , make sure your design does not negatively impact if same Batch runs multiple time
Below sample code, shows how we can add 300+ job in single transaction using this framework
//Code snippet to submit Batch and Queuable
for(Integer i = 0; i<300;i++){
BatchDemo b = new BatchDemo('#B');
AsyncApexFramework.submitBatch(b,1,99,true);
AsyncApexFramework.submitQueueable(new QueueableDemo(),99,true);
}
AsyncApexFramework.flush();
Feel free to add your feedback and findings on this.
Leave a Reply