function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
ssoftwaressoftware 

System.LimitException: ads:Too many DML statements: 151

Hi All,

List<CronTrigger> lstJobs = [SELECT Id FROM CronTrigger WHERE CronJobDetail.Name LIKE '%myReports%'];
for(CronTrigger ct : lstJobs) system.abortJob(ct.Id);

I run the above code on a daily basis to clean up some old scheduled batch jobs, and I am getting the limitexception:
System.LimitException: ads:Too many DML statements: 151

I undestand that bulkifying the above would solve the issue - similar to other DML operations on standard and custom objects.

My question is - how to do bulkify this operation? Is there a way to mass delete schduled jobs as abortJob() function seems to take only one Job Id at a time?

Kind Regards
Madhav
Best Answer chosen by ssoftware
SeAlVaSeAlVa
Hi,


I haven't tryied myself but, have you tried something like...
public class yourClassName {

  @future
  public static void massDeleteJobs(List<ID> paramIDsToAbort) {
    Integer i = 0;
    while (i < 150 && paramIDsToAbort.size() > 0) {
      System.abortJob(paramIdsToAbort.remove(0));
      i++;
    }
    if (paramIDsToAbort.size() > 0) {
      yourClassName.massDeleteJobs(paramIDsToAbort);
    }
  }
}


And to make the first call
yourClassName.massDeleteJobs(new Map<ID,CronTrigger>([SELECT Id FROM CronTrigger WHERE CronJobDetail.Name LIKE '%myReports%']).keySet());

Regards

[And remember, if it helps, mark it as "Best Answer", if not ... reply ;) ]

All Answers

SeAlVaSeAlVa
Hi,


I haven't tryied myself but, have you tried something like...
public class yourClassName {

  @future
  public static void massDeleteJobs(List<ID> paramIDsToAbort) {
    Integer i = 0;
    while (i < 150 && paramIDsToAbort.size() > 0) {
      System.abortJob(paramIdsToAbort.remove(0));
      i++;
    }
    if (paramIDsToAbort.size() > 0) {
      yourClassName.massDeleteJobs(paramIDsToAbort);
    }
  }
}


And to make the first call
yourClassName.massDeleteJobs(new Map<ID,CronTrigger>([SELECT Id FROM CronTrigger WHERE CronJobDetail.Name LIKE '%myReports%']).keySet());

Regards

[And remember, if it helps, mark it as "Best Answer", if not ... reply ;) ]
This was selected as the best answer
ssoftwaressoftware
Hi SeAlVa,

Thank you for your quick reply. I appreciate it. Using @future is an interesting idea and I will check it out to see if it helps. My suspicion is that it will not because in the future function, you are still looping through for each job and then aborting the job (so 1 DML for each job id). Thus it is not really bulkifying the DML statements into one mass delete DML statement.

I also see that the code is using a counter which limits the process to under 150 to avoid the limit exception.

I have tested the following code similarly, and it works due to the LIMIT:

List<CronTrigger> lstJobs = [SELECT Id FROM CronTrigger WHERE CronJobDetail.Name LIKE '%myReports%' LIMIT 50];
for(CronTrigger ct : lstJobs) system.abortJob(ct.Id);

However I am not very happy with this solution, as it looks like a workaround. But it seems like this is probably the only way for the time being.

Thanks for your input again. I appreciate it.

Kind Regards
Madhav