java-确保Spring Quartz作业执行不重叠
我有一个Java程序,每20秒从Spring Qquartz执行一次。 有时只需几秒钟即可执行,但是随着数据量的增加,我确信它会运行20秒或更长时间。
在一个实例仍在执行时,如何防止Quartz触发/触发作业? 触发2个在数据库上执行相同操作的作业效果不佳。 有没有办法可以进行某种同步?
7个解决方案
134 votes
石英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*/}
}
Dónal answered 2020-06-25T01:40:42Z
31 votes
如果您需要做的是每20秒发射一次,则Quartz是严重的过度杀伤力。 ScheduledExecutorService应该足以完成该工作。
ScheduledExecutorService还提供了两种用于调度的语义。 “固定比率”将尝试每20秒运行一次作业,而不会出现重叠,而“固定延迟”将尝试在第一个作业结束与下一个作业开始之间间隔20秒。 如果要避免重叠,则固定延迟是最安全的。
skaffman answered 2020-06-25T01:39:55Z
19 votes
万一有人引用此问题,StatefulJob已被弃用。 他们现在建议您改用注解...
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class TestJob implements Job {
这将解释这些注释的含义...
注释会导致行为 他们的名字描述-多个 作业的实例将不会 允许同时运行(考虑 作业中有代码的情况 execute()方法需要34秒 运行,但预定 每30次重复触发一次 秒),并将获得其JobDataMap 内容重新存在于 每次之后的调度程序的JobStore 执行。 为此目的 仅举例 @PersistJobDataAfterExecution 注释确实是相关的,但是 总是明智的使用 @DisallowConcurrentExecution 带有注释,以防止 已保存数据的竞争条件。
gshauger answered 2020-06-25T01:41:11Z
4 votes
如果您使用弹簧石英,我认为您必须像这样配置
Paul answered 2020-06-25T01:41:31Z
2 votes
我不确定您是否需要同步,因为第二个任务将一直阻塞到第一个任务完成,您最终将积压。 您可以将作业放在队列中,但是从您的描述看来,队列可能会无限期增长。
我将研究ReadWriteLocks,并让您的任务在运行时设置一个锁。 以后的任务可以检查此锁,如果旧任务仍在运行,则立即退出。 我从经验中发现,这是解决此问题的最可靠方法。
也许还会发出警告,以便您知道遇到问题并相应地增加时间间隔?
Brian Agnew answered 2020-06-25T01:42:00Z
0 votes
把他们排队
即使时间超过20秒,当前作业也应完成,然后应从队列中取出下一个作业。
或者,您也可以将时间增加到合理的数量。
Asad Khan answered 2020-06-25T01:42:29Z
0 votes
您可以使用信号量。 发出信号量后,放弃第二项工作,等到下一次触发时间。
Salandur answered 2020-06-25T01:42:49Z
这篇博客讨论了如何在Java Spring Quartz中确保作业执行时不重叠。当作业执行时间超过预定的触发间隔时,作者提出了使用StatefulJob、@DisallowConcurrentExecution注解、ScheduledExecutorService、队列、信号量等多种解决方案来防止并发执行,以避免对数据库造成不良影响。
1419

被折叠的 条评论
为什么被折叠?



