1

I created a basic batch class.

global class MyBatchClass implements Database.Batchable<sObject> {

    global Database.QueryLocator start(Database.BatchableContext bc) {
        return Database.getQueryLocator('SELECT Id, Name FROM Account');
    }

    global void execute(Database.BatchableContext bc, List<Account> scope) {
        for(Account acc : scope) {
            acc.Name = 'Updated-' + acc.Name;
        }
        update scope;
    }

    global void finish(Database.BatchableContext bc){
        System.debug('Batch job completed.');
    }
}

Below is the schedulable class

global class MyBatchClassSchedule implements Schedulable{

    global void execute(SchedulableContext sc) {
        MyBatchClass batchJob = new MyBatchClass();
        Database.executeBatch(batchJob);
    }
    
}

Now, I am trying to schedule this batch class using the following CRON expression

String hour = String.valueOf(Datetime.now().hour()); 
String min =String.valueOf(Datetime.now().addMinutes(5).minute()); 
String ss = String.valueOf(Datetime.now().second()); 
String nextFireTime = ss + ' ' + min + ' ' + hour + ' * * ?';
    
String jobName = 'MyBatchSchedulerJob'; String cronExpression = '0 */5 * * * ?'; 
System.schedule(jobName, cronExpression, new MyBatchClassSchedule());

It is scheduling the class for the first 5 minutes. eg If it starts at 12:00AM, then the next scheduled time comes 12:05. But when it starts again at 12:05, the next scheduled time is 12:05 instead of 12:10. What am I doing wrong?

2

3 Answers 3

3

In Salesforce, scheduled jobs cannot be scheduled less than one hour apart. If you want to have this process run every five minutes, you will need to schedule 12 jobs five minutes apart.

3

You can run an apex job every 1 hour using CRON expression by default but you can schedule this job 12 times in one hour at 5 min duration.

You have a Scheduler class MyBatchClassSchedule and want to run the schedule a class every five minutes, then use the CRON expression below.

How to run follow the below process:

  • Go to your developer console

  • Open Execute Anonymous Window

  • Copy and Paste the Below code and click on the execute button.

    System.schedule('MyBatchSchedulerJob 1', '0 00 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 2', '0 05 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 3', '0 10 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 4', '0 15 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 5', '0 20 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 6', '0 25 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 7', '0 30 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 8', '0 35 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 9', '0 40 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 10', '0 45 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 11', '0 50 * * * ?', new MyBatchClassSchedule()); System.schedule('MyBatchSchedulerJob 12', '0 55 * * * ?', new MyBatchClassSchedule());

After this, if you want To check apex class in scheduled or not then:

  • Go to Setup
  • Jobs
  • Scheduled Jobs

For more detail refer to this: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_scheduler.htm

0
3

If you are happy with timing drift, where you simply want to ensure that you have processing done every 5 minutes or so, an alternative to Schedulable is to actually have your Batchable implementation do "self-scheduling", using System.scheduleBatch from the finish method. The code would pass this and 5 as the (first) two parameters to System.scheduleBatch.

Processing is started by simply running the Batchable via System.executeBatch, just the once. It will keep itself going as needed.

The advantage of this approach is that the 5 minute delay is between executions and you won't have two executions accidentally bump into each other. (You may find the batch takes much longer than 5 minutes to run and you'd have multiple versions running concurrently against the same data if you are not careful. That cannot happen with this approach unless you actually execute the batch more than once, manually.)

An alternative option is use a Queueable that also implements Finalizer, instead of Schedulable.

In this approach, the Finalizer's execute method just self-enqueues (on success and on failure) with a minimum delay of 5 minutes (using System.enqueueJob(queueable, delay), passing in this as the queueable and 5 as the delay).

To start the process you would simply enqueue the Queueable once via System.enqueueJob, likely without a delay.

This has the same advantages if you can process everything in one execute of the Queueable.

2
  • This is the way.
    – Jan J
    Commented Dec 9, 2023 at 21:07
  • @JanJulian feel free to upvote.
    – Phil W
    Commented Dec 9, 2023 at 21:18

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .