You need to sign in to do that
Don't have an account?

Limits on Batch Apex with Trigger: Will it be 5 or 105?
I'm new to developing and trying to determine if I will get errors thrown in my batch apex code. The purpose is to: upon deactivation of a user (trigger, which I understand isn't best practice but don't know another way the batch can be automatically started w/o checking for deactivated users every night), all of the leads of deactivated user are queried to change the OwnerId to a catchall user. The trick is that one user may have as many as 200,000 leads that need to be updated, hence why I am using batch apex. Two questions:
1. How many batch jobs will be activated with each deactivated user? (I think the answer is one?)
2. Will the batch job be sent to the Flex Queue as 'holding' and then to active, giving the org 105 possible batch jobs to be held/processed at once before throwing errors, or will it bypass Flex Queue, thereby limiting the org to only 5 batch jobs at a time?
I hope my questions make sense, and I appreciate any help. I have spent many hours researching this as a newbie. In case it's relevant, my code is below:
Trigger:
trigger BatchUpdateTrigger2 on User (after update) { //Map will keep deactivated users and their Id's, to be used later in batch Apex Map<id, User> DeactivatedUsers = new Map<id, User>(); //Check all users in trigger, first if the IsActive button has been newly changed and if it now says that the user is not active for (Integer i=0;i<Trigger.new.size();i++) { if (Trigger.new[i].IsActive!=Trigger.old[i].IsActive && Trigger.new[i].IsActive == false) { DeactivatedUsers.put(Trigger.new[i].Id, Trigger.new[i]); } } // Make sure that there are users to be processed if (DeactivatedUsers.size() > 0) { BatchUpdateLeads objBatchUpdateLeads=new BatchUpdateLeads(DeactivatedUsers); Database.executeBatch(objBatchUpdateLeads); } }
Batch Apex Class:
global class BatchUpdateLeads implements Database.Batchable<SObject> { //Save a public variable to hard-code the catchall user that will become lead owner public Id GenericUserId = '0054P000009pLkrQAE'; //map of userid - user that retrieves deactivated user(s) from previous trigger Map<Id, User> DeactivatedUsersMap = new Map<Id, User>(); global BatchUpdateLeads(Map<Id, User> DeactivatedUsers) { DeactivatedUsersMap = DeactivatedUsers; } //Search for the leads whose OwnerId is the deactivated user(s) global Database.QueryLocator start(Database.BatchableContext BC) { return DataBase.getQueryLocator([SELECT Id, OwnerId FROM Lead WHERE OwnerId IN : DeactivatedUsersMap.keySet()]); } //For leads whose owner was deactivated, change OwnerId to the catchall user global void execute(Database.BatchableContext BC, List<sObject> scope){ List<Lead> leads = (List<lead>)scope; for (Lead l: leads){ l.OwnerId = GenericUserId;} //Check that there are leads to be updated, then update if (leads.size() > 0){ update leads; } } global void finish(Database.BatchableContext BC) { //Send an email to system admin after the batch completes (fill in email) Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); String[] toAddresses = new String[] {'xxxxxxx@gmail.com'}; mail.setToAddresses(toAddresses); mail.setSubject('Apex Batch Job is done'); mail.setPlainTextBody('The Batch Apex Job Processed Successfully'); Messaging.sendEmail(new Messaging.SingleEmailMessage[] { mail }); } }
- The User trigger will kick off the BatchUpdateLeads logic each time the trigger is executed. Salesforce typically processes 200 records at a time. So if you updated less than 200 Users to Inactive then it will fire once. More than 200 and it will fire once per chunk of 200 records. It is possible to increase and decrease the number of records being processed but in general your assumption about the logic firing once is valid.
- As long as the Apex Flex Queue is active for the Org then, yes, when your BatchUpdateLeads logic is started and is set to a holding status then it will be added to the queue. So you should be permitted up to 100 jobs in that queue.
In general, I don't recommend kicking off a batch Apex job from Trigger. Another approach for your scenario might be a boolean (checkbox) on the User record that gets updated by your trigger in real-time. Then schedule the batch class to run at night and process the Users that have the flag set and remove the boolean designation to denote the processing is complete. The reason for this approach would be to prevent User disruption while changing ownership on so many Leads during business hours.-greg
All Answers
- The User trigger will kick off the BatchUpdateLeads logic each time the trigger is executed. Salesforce typically processes 200 records at a time. So if you updated less than 200 Users to Inactive then it will fire once. More than 200 and it will fire once per chunk of 200 records. It is possible to increase and decrease the number of records being processed but in general your assumption about the logic firing once is valid.
- As long as the Apex Flex Queue is active for the Org then, yes, when your BatchUpdateLeads logic is started and is set to a holding status then it will be added to the queue. So you should be permitted up to 100 jobs in that queue.
In general, I don't recommend kicking off a batch Apex job from Trigger. Another approach for your scenario might be a boolean (checkbox) on the User record that gets updated by your trigger in real-time. Then schedule the batch class to run at night and process the Users that have the flag set and remove the boolean designation to denote the processing is complete. The reason for this approach would be to prevent User disruption while changing ownership on so many Leads during business hours.-greg
-greg