@DisallowConcurrentExecution注解未生效求助:同一Job实例仍并发执行
我之前也碰到过一模一样的问题!折腾了快一周才找到根源,给你梳理几个最容易出错的点,你可以逐一排查:
注解位置完全错了:这个注解必须直接标注在你的Job实现类上,不能加在创建JobDetail的配置方法、触发器类或者其他任何地方。比如你要是把
@DisallowConcurrentExecution贴在@Bean public JobDetail myJobDetail()这个方法上,那完全没用,必须贴在实现了Job接口或者继承QuartzJobBean的那个类上。JobDetail其实不是同一个实例:你说“所有触发器用同一JobDetail”,但Quartz里JobDetail的唯一性是group + name组合决定的,不是只看name。如果你的代码里给不同触发器关联的JobDetail设置了不同的group,哪怕name一样,也是两个完全不同的JobDetail,注解自然不会生效。赶紧检查下你创建JobDetail的代码,是不是group参数统一了?
Job类被多次实例化了:如果你的Job类被Spring(或者你用的容器)创建了多个实例,比如设置了
@Scope("prototype"),或者不同的配置类都初始化了它,那Quartz会拿到多个Job实例,而@DisallowConcurrentExecution是针对同一个JobDetail对应的Job实例生效的,多个实例就会并发执行。确认下你的Job类是不是单例模式(Spring默认就是单例,除非你改了)。混用了过时的StatefulJob接口:如果你同时实现了
StatefulJob这个旧接口(Quartz 2.x之后已经被@DisallowConcurrentExecution和@PersistJobDataAfterExecution替代),可能会和注解产生冲突。建议直接移除StatefulJob的实现,只保留@DisallowConcurrentExecution注解。Quartz版本存在bug:某些旧版本的Quartz(比如2.2.x之前的部分版本)在动态创建JobDetail时,注解可能无法被正确识别。可以尝试升级到稳定的新版本,比如2.3.x或者更高版本,说不定问题直接解决。
框架配置覆盖了注解:如果你用的是Spring Boot这类封装了Quartz的框架,检查下有没有配置项覆盖了注解的行为。比如
application.properties里的spring.quartz.job-store.*相关配置,有没有强制开启并发的设置?
给你贴个正确的用法示例,对比下你的代码:
import org.quartz.DisallowConcurrentExecution; import org.quartz.Job; import org.quartz.JobExecutionContext; import org.quartz.JobExecutionException; @DisallowConcurrentExecution public class SafeConcurrentJob implements Job { @Override public void execute(JobExecutionContext context) throws JobExecutionException { // 这里写你的任务逻辑,同一JobDetail的触发器不会并发执行这个方法 } }
内容的提问来源于stack exchange,提问作者nafi

