Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ensure that Spring Quartz job execution doesn't overlap

I have a Java program that executes from Spring Qquartz every 20 seconds. Sometimes it takes just few seconds to execute, but as data gets bigger I'm sure it run for 20 seconds or more.

How can I prevent Quartz from firing/triggering the job while one instance is still being executed? Firing 2 jobs performing same operations on a database would not be so good. Is there a way I can do some kind of synchronization?

like image 290
ant Avatar asked Oct 28 '09 11:10

ant


People also ask

How do I Unschedule a Quartz job?

We can unschedule a Job by calling the unschedule() method of the Scheduler class and passing the TriggerKey . If the related job does not have any other triggers, and the job is not durable, then the job will also be deleted.

Why we should not use Quartz scheduler?

It has no built-in UI for configuration or monitoring, no useful and reasonably searchable logging or historical review, no support for multiple execution nodes, no administration interface, no alerts or notifications, not to mention buggy recovery mechanisms for failed jobs and missed jobs.

How do you schedule multiple jobs using Quartz?

If you want to schedule multiple jobs in your console application you can simply call Scheduler. ScheduleJob (IScheduler) passing the job and the trigger you've previously created: IJobDetail firstJob = JobBuilder. Create<FirstJob>() .

How does Quartz Scheduler work internally?

Quartz scheduler allows an enterprise to schedule a job at a specified date and time. It allows us to perform the operations to schedule or unschedule the jobs. It provides operations to start or stop or pause the scheduler. It also provides reminder services.


2 Answers

Quartz 1

If you change your class to implement StatefulJob instead of Job, Quartz will take care of this for you. From the StatefulJob javadoc:

stateful jobs are not allowed to execute concurrently, which means new triggers that occur before the completion of the execute(xx) method will be delayed.

StatefulJob extends Job and does not add any new methods, so all you need to do to get the behaviour you want is change this:

public class YourJob implements org.quartz.Job {     void execute(JobExecutionContext context) {/*implementation omitted*/} } 

To this:

public class YourJob implements org.quartz.StatefulJob {     void execute(JobExecutionContext context) {/*implementation omitted*/} } 

Quartz 2

In version 2.0 of Quartz, StatefulJob is deprecated. It is now recommended to use annotations instead, e.g.

@DisallowConcurrentExecution public class YourJob implements org.quartz.Job {     void execute(JobExecutionContext context) {/*implementation omitted*/} } 
like image 170
Dónal Avatar answered Sep 17 '22 17:09

Dónal


If all you need to do is fire every 20 seconds, Quartz is serious overkill. The java.util.concurrent.ScheduledExecutorService should be perfectly sufficient for that job.

The ScheduledExecutorService also provides two semantics for scheduling. "fixed rate" will attempt to run your job every 20 seconds regardless of overlap, whereas "fixed delay" will attempt to leave 20 seconds between the end of the first job and the start of the next. If you want to avoid overlap, then fixed-delay is safest.

like image 45
skaffman Avatar answered Sep 20 '22 17:09

skaffman