5

I was thinking of calling a batch class from my trigger. Is is advisable to do that? As batch will have asynchronous execution with respect to trigger.

9

You can call a batch from a trigger, but you need to be aware of potential limits you could hit. You can only have 5 batch jobs queued or executing at once. If your trigger calls batch jobs each time, then you could quickly exceed that limit. See http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm

8

These answers are somewhat valid, but since you can query the state of a running batch you can ensure that your batch is a singleton.

    Boolean isExecuting = (([SELECT COUNT()
                    FROM AsyncApexJob
                   WHERE ApexClassId IN (
                                    SELECT Id 
                                      FROM ApexClass 
                                     WHERE Name = 'Blah'
                                       )
                 ]) == 0) ? false : true ;
    if(isExecuting){
        return;
    }
    Database.executeBatch(new Blah(),1); 

if you protect your batch call you can also schedule the batch to run every hour. In that way it acts in almost realtime most of the time and a tail call executes every hour for anything that is missed.

5

As Daniel has said, you can only have five batch job running so calling batch from a trigger is almost certainly not a good idea.

If you simply want to have asynchronous execution with respect to the trigger, then you can instead call methods annotated with the @Future annotation

https://www.salesforce.com/us/developer/docs/apexcode/Content/apex_classes_annotation_future.htm

  • I was more thinking towards any other best practices that I might be breaking apart from of course the max 5 batch size limit.. – Kaushik Ray Mar 26 '14 at 16:42
3

At a time only 5 apex batch jobs can be processed. Flex Queue does allow more than 5 concurrent batch jobs but it simply lines up the remaining jobs and keep their status as "Holding". So, apparently user feels that more than 5 jobs have been submitted but they all go in the "Holding" status.

Flex queue itself has a limit of holding up to 100 apex batch jobs only. Therefore, in a live org with thousands of users working simultaneously, lining up apex batch jobs from a trigger will create issues. If the apex flex queue reaches 100 jobs and at the same time a user tries to update something that is further triggering an apex batch then s(he) will see the following error on screen:

"System.AsyncException: You've exceeded the limit of 100 jobs in the flex queue for org X. Wait for some of your batch jobs to finish before adding more. To monitor and reorder jobs, use the Apex Flex Queue page in Setup".

1

FlexQueue now allows more than 5 concurrent batch jobs at once. https://developer.salesforce.com/blogs/engineering/2014/05/flex-batch-apex-muscles-flexqueue.html

  • 1
    neena - tahnks for joining SFSE. This is a tantalizing answer - "tantalizing" in that it suggests a line of inquiry but doesn't really answer the original question (which frankly, doesn't show any research on the part of the poster and would normally be marked as closed by the Community). If you look at other answers people give, there is usually more explanation provided – cropredy Dec 28 '15 at 22:38
  • 3
    @Neena - Just because flex queue allows more than 5 jobs does NOT mean that just lining them up due to trigger execution is a good practice. – Eric Dec 28 '15 at 23:45
-1

In recent times, I have used the below approach and it works smoothly. Call the below code from trigger and put checks on the maximum number of jobs submitted in the flex queue + maximum number of jobs that can be scheduled. With this approach, we can process almost any number of recrods.

5 batches of 200 batch size will be concurrently processed. 100 jobs of 200 batch size can be in holding status in the flex queue. Once there are no vacant spaces in the flex queue, schedule the apex jobs for 10 mins. There could maximum 10 batch jobs of 200 batch size(on trigger context) can be scheduled and since the schedule time is 10 mins, we can expect that the flex queues are emptied by that time. So in the next iteration again records can be piled up into the flex queue.

// Checking the number of batch jobs have been submitted in the Apex Flex Queue. 100 is the limit.
            Boolean isExecuting = (([SELECT COUNT() FROM AsyncApexJob WHERE ApexClassId IN (SELECT Id FROM ApexClass WHERE Name = 'BatchUpdatesAccountRelatedRecords') AND Status IN ('Holding')]) == 100) ? true : false ;
            if(isExecuting){
                //checking if the maximum number jobs have been scheduled or not. 10 is the limit.
                if(!UtilClass.MaxScheduledJobsReached()){
                    // schedule the batch if maximum number of batch jobs is not scheduled. 
                    String cronID = System.scheduleBatch(new BatchUpdatesAccountRelatedRecords(accnts), 'Customer Group Update', 10);
                }else{
                    return;
                }
            }
            Id bacthJobId = Database.executeBatch(new BatchUpdatesAccountRelatedRecords(accnts));
            System.debug('Submitted Job Id'+bacthJobId);
  • This doesn't answer the question, it just presents a single case where a batch was called from a trigger. If the trigger architecture is more complex and the batch class fires other triggers that may initiate other batch classes things will get out of hand very quickly. – AvailableName Feb 27 at 15:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.