You need to sign in to do that
Don't have an account?
Scheduled Batch Apex class cannot access static variables or get properties changed after scheduled
Considering I have to run several different batch processes in my org and the governance limit allowing only 5 queued batch processes at a time, I took this idea and i tried to take it to the next level to avoid using a custom setting to store the current JobId. My idea was simple. In a nutshell I was going to keep the JobId for that execution inside the Apex Batch, and having the finish method using that value to abort the scheduled job.
global with sharing abstract class INS_aOrchestratedBatch implements Database.Batchable<sObject> { protected final integer BATCHS_INTERVAL_MIN = 2; private List<INS_aOrchestratedBatch> batchProcessOnQueue; private Map<string, string> parameters; protected string query; protected string name; global string getName(){ return name; } global Id jobId{set;get;} global INS_aOrchestratedBatch(List<INS_aOrchestratedBatch> abatchProcessOnQueue, Map<string, string> aparameters, string pname){ System.debug('Building INS_aOrchestratedBatch'); batchProcessOnQueue = abatchProcessOnQueue; parameters = aparameters; name = pname; } global virtual Database.QueryLocator start(Database.BatchableContext BC){ return Database.getQueryLocator(query); } global abstract void execute(Database.BatchableContext BC, List<sObject> scope); global virtual void finish(Database.BatchableContext BC){ sendJobStatus(BC); cancelPreviousJobSchedule(jobId); scheduleNextBatch(BATCHS_INTERVAL_MIN); } protected virtual string scheduleNextBatch(Integer minutesAfter){ string returnJobId; if(batchProcessOnQueue.size() > 0 ){ integer nextBatchIndex = batchProcessOnQueue.size() - 1; INS_aOrchestratedBatch nextBatch = batchProcessOnQueue.remove(nextBatchIndex); DateTime n = datetime.now().addMinutes(minutesAfter); String cron = ''; cron += n.second(); cron += ' ' + n.minute(); cron += ' ' + n.hour(); cron += ' ' + n.day(); cron += ' ' + n.month(); cron += ' ' + '?'; cron += ' ' + n.year(); INS_OrchestratedBatchScheduler scheduler = new INS_OrchestratedBatchScheduler(nextBatch); returnJobId = System.schedule('Notification Batch - ' + nextBatch.Name , cron, scheduler); system.debug('scheduleNextBatch --------->' + returnJobId); //We setup the jobId on the same class so it cancel itself at the end nextBatch.jobId = returnJobId; } return returnJobId; } private virtual void cancelPreviousJobSchedule(Id jobId){ if(jobId != null){ System.abortJob(jobId); } } }
You will find out that that I am using a list of chained process and also a wrapper to schedule, but that doesn't make any difference to understand the problem. The interesting part is in this line :
returnJobId = System.schedule('Notification Batch - ' + nextBatch.Name , cron, scheduler); system.debug('scheduleNextBatch --------->' + returnJobId); //We setup the jobId on the same class so it cancel itself at the end nextBatch.jobId = returnJobId;
Where I schedulle the job and then I tried to setup a properly so it can auto abort the job in the finish.
However when the class hits the finish, the jobId property is null, My idea here is that when salesforce queues the class in the scheduller, the instance is copied somewhere else and you cannot modify the values of what is already queued. i also tried with a static variable with the same results.
I ended up just queryng the CronDetails (only available in W'14) together with the CronTrigger object, to get the job Id based on my Schedule name.
Any ideas about this behavior of schedulled classes? I am curious how it works as it is not documented.
Thanks