I’d like to propose a new way of working with scheduled batch classes. I’ve worked on several hundred Salesforce projects in the past few years and often see batch scheduling classes being created per scheduling requirement and it grinds my OCD – not in a good way. In most cases you should only need one “Batch Scheduler” per Org, let me demonstrate how and why.
The Universal Batch Scheduler™
Requirements
Let’s assuming you have a batch class that you need to run on a repeated schedule*, such a class signature is given below. That class will have to obey some conventions such as implementing the Batchable interface as shown in the standard documentation.
[code language=”Java”]
global class MyBatch implements Database.Batchable<SObject> {
// …
}
[/code]
* For one off, schedule execution of batch classes you can use the System.ScheduleBatch() method.
The Scheduler
Now you might be tempted to created a scheduled Apex class specifically for this batch class, but by using the principle of polymorphism you could create a universal scheduler instead.
First of all you’ll need to implement the required interface for scheduled Apex classes as shown below.
[code language=”Java”]
global class BatchScheduler implements Schedulable {
// …
}
[/code]
Next assign global, class-level variables which will be used to access the parameter values required when executing a batch class. Note that we’re creating a variable called “batchClass” whose type is the interface Database.Batchable. This means that any class that implements this interface can be assigned to this variable, this behaviour is called polymorphism.
[code language=”Java”]
global Database.Batchable<SObject> batchClass{get;set;}
global Integer batchSize{get;set;} {batchSize = 200;}
[/code]
And finally implement the method required by the Scheduleable interface and use the variables to kick off the execution of a batch class.
[code language=”Java”]
global void execute(SchedulableContext sc) {
database.executebatch(batchClass, batchSize);
}
[/code]
Et voila! You now have a class that can be used to schedule any batch class in your Org. The final code being:
[code language=”Java”]
global class BatchScheduler implements Schedulable {
global Database.Batchable<SObject> batchClass{get;set;}
global Integer batchSize{get;set;} {batchSize = 200;}
global void execute(SchedulableContext sc) {
database.executebatch(batchClass, batchSize);
}
}
[/code]
In order to use it you would have to initiate the schedule from an anonymous block (Developer Console, Eclipse, Mavensmate etc.). For example I would schedule my batch class using something like this:
[code language=”Java”]
// Instantiate the batch class
MyBatch myBatch = new MyBatch();
// Instantiate the scheduler
BatchScheduler scheduler = new BatchScheduler();
// Assign the batch class to the variable within the scheduler
scheduler.batchClass = myBatch;
// Run every day at 1pm
String sch = ‘0 0 13 * * ?’;
System.schedule(‘MyBatch – Everyday at 1pm’, sch, scheduler);
[/code]
There may be cases where the universal batch scheduler is not appropriate i.e. special pre-work has to be done in the scheduling class, but in most cases I’ve seen it’ll do the job. Hopefully this’ll help you make your Orgs a little neater too.
Straightforward and elegant. Thanks for sharing. 🙂
wow, this really works.
Where does it keep remember which job which time should be run?
Reblogged this on patlatus and commented:
The Universal Batch Scheduler™.
Schedule any batch. Any time.