[SalesForce] Schedulable – Apex CPU time limit exceeded

We have this nightly code that runs in our org. Recently, we started receiving APEX CPU Time limit exceeded errors and we're looking for ways top optimize the code. Anyone have any suggestions on how to optimize?

Some Notes:

  1. Our Contact object has about 5 validation rules and about a dozen workflow rules, so that slow things down a bit – and it shows that in the detailed debug logs.

  2. The second for loop is necessary to trigger a flag TriggerNextDateEmail, that then triggers a time-based workflow rule. Based on the date that is being updated, that time based workflow sends an email to the Contact. You can't combine that second for loop into the first because then the flag doesn't get shut off and then turned back on. Without that off-on, the time based workflow doesn't get re-triggered (this is a recurring email that goes out every several days or so)

  3. So far this is failing on an update that is working though about 850 contacts

global class cls_update_Next_Date implements Schedulable { global void execute(SchedulableContext ctx) { list conlist = new list(); list updateconlist = new list(); conlist.clear(); updateconlist.clear(); conlist = [select id,Status__c,NextDate__c,Next_Date_Calculation__c from Contact where NextDate__c <=:date.Today() and Status__c = 'Enrolled'];

for(contact con:conlist) { con.NextDate__c = con.Next_Date_Calculation__c; con.TriggerNextDateEmail__c = false; //need to reset this so email under time based workflow trigger is sent updateconlist.add(con); } if(updateconlist.size()>0) { update updateconlist; } // TriggerNextDateEmail__c has been set to false, now need to reset it to true so the email is re-triggered updateconlist.clear(); for(contact con:conlist) { con.TriggerNextDateEmail__c = true; updateconlist.add(con); } if(updateconlist.size()>0) { update updateconlist; } } }

Best Answer

Move the processing into a batch implementation. Then the scheduled class with just start the batch processing.

The batch will breakup the SOQL results. Then you can use the scope parameter for Database.executeBatch to limit the number of Contacts per batch execution.

Note that each batch execution gets separate governor limits.

Related Topic