确保 Spring Quartz 作业执行不会重叠

我有一个Java程序,每20秒从Spring Qquartz执行一次。有时它只需要几秒钟来执行,但随着数据变大,我确信它会运行20秒或更长时间。

如何防止 Quartz 在一个实例仍在执行时触发/触发作业?在数据库上执行相同操作时触发 2 个作业不会很好。有没有办法进行某种同步?


答案 1

石英 1

如果您将类更改为实现StatefulJob而不是Job,Quartz将为您处理此事。来自 StatefulJob javadoc

有状态作业不允许并发执行,这意味着在 execute(xx) 方法完成之前出现的新触发器将被延迟。

StatefulJob 扩展了 Job,并且不添加任何新方法,因此要获得所需的行为,您需要做的就是更改以下内容:

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

对此:

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

石英 2

在 Quartz 的 2.0 版中,已弃用。现在建议改用注释,例如StatefulJob

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

答案 2

如果你需要做的就是每20秒点火一次,那么Quartz就严重过度了。对于这项工作来说,应该完全足够了。java.util.concurrent.ScheduledExecutorService

还提供了两种用于调度的语义。“固定速率”将尝试每 20 秒运行一次作业,而不考虑重叠,而“固定延迟”将尝试在第一个作业结束和下一个作业开始之间留出 20 秒。如果要避免重叠,则固定延迟是最安全的。ScheduledExecutorService


推荐