Java 石英作业注释@DisallowConcurrentExecution实现

Java 石英作业注释@DisallowConcurrentExecution实现,java,quartz-scheduler,quartz,Java,Quartz Scheduler,Quartz,我不熟悉石英。我发现了quartz library提供的@DisallowConcurrentExecution注释,文档上说: “将{@link Job}类标记为不能同时执行多个实例的注释(其中实例基于{@link jobdail}定义,或者换句话说,基于{@link JobKey})。” DisallowConcurrentExecution.java写为: @Documented @Retention(RetentionPolicy.RUNTIME) @Target(ElementType

我不熟悉石英。我发现了quartz library提供的
@DisallowConcurrentExecution
注释,文档上说:

“将{@link Job}类标记为不能同时执行多个实例的注释(其中实例基于{@link jobdail}定义,或者换句话说,基于{@link JobKey})。”

DisallowConcurrentExecution.java
写为:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface DisallowConcurrentExecution {

}
但是,我找不到一个实现,该实现实际上可以解决同一个作业没有并发执行的问题。这对我来说是新的,所以有人可以帮助我解释内部实现逻辑


我试图查找用法,但只在调用JobDetailFactoryBean.java的类
方法中找到了它。免责声明:我没有参与quartz项目。我在这里的所有评论都是出于我自己的好奇而对此事进行的调查,可能遗漏了一些信息

首先要知道的是,JobDetailImpl将检查注释是否存在,并使此信息在方法中可用

/**
 * @return whether the associated Job class carries the {@link DisallowConcurrentExecution} annotation.
 */
public boolean isConcurrentExectionDisallowed() {

    return ClassUtils.isAnnotationPresent(jobClass, DisallowConcurrentExecution.class);
}
然后您可以看到此方法在系统的不同部分中进行了检查

例如,JobStoreSupport会在此处进行检查,如果存在注释,则会检查块状态:

    if (job.isConcurrentExectionDisallowed() && !recovering) { 
        state = checkBlockedState(conn, job.getKey(), state);
    }
这里是实际验证发生的地方,让Quartz决定在该实例上运行还是不运行作业

org.quartz.impl.jdbcjobstore.JobStoreSupport#checkBlockedState

    /**
     * Determines if a Trigger for the given job should be blocked.  
     * State can only transition to STATE_PAUSED_BLOCKED/BLOCKED from 
     * PAUSED/STATE_WAITING respectively.
     * 
     * @return STATE_PAUSED_BLOCKED, BLOCKED, or the currentState. 
     */
    protected String checkBlockedState(
            Connection conn, JobKey jobKey, String currentState)
        throws JobPersistenceException {

    // State can only transition to BLOCKED from PAUSED or WAITING.
    if ((!currentState.equals(STATE_WAITING)) &&
        (!currentState.equals(STATE_PAUSED))) {
        return currentState;
    }

    try {
        List<FiredTriggerRecord> lst = getDelegate().selectFiredTriggerRecordsByJob(conn,
                jobKey.getName(), jobKey.getGroup());

        if (lst.size() > 0) {
            FiredTriggerRecord rec = lst.get(0);
            if (rec.isJobDisallowsConcurrentExecution()) { // OLD_TODO: worry about failed/recovering/volatile job  states?
                return (STATE_PAUSED.equals(currentState)) ? STATE_PAUSED_BLOCKED : STATE_BLOCKED;
            }
        }

        return currentState;
    } catch (SQLException e) {
        throw new JobPersistenceException(
            "Couldn't determine if trigger should be in a blocked state '"
                + jobKey + "': "
                + e.getMessage(), e);
    }

}
/**
*确定是否应阻止给定作业的触发器。
*状态只能转换为状态\u暂停\u阻止/阻止自
*已暂停/分别声明您正在等待。
* 
*@返回状态\u暂停\u已阻止、已阻止或当前状态。
*/
受保护字符串checkBlockedState(
连接连接,作业键,作业键,字符串当前状态)
抛出JobPersistenceException{
//状态只能从暂停或等待转换为阻止。
如果(!currentState.equals(STATE_WAITING))&&
(!currentState.equals(STATE_暂停))){
返回电流状态;
}
试一试{
List lst=getDelegate()。选择FiredTriggerRecordsByJob(连接,
jobKey.getName(),jobKey.getGroup());
如果(lst.size()>0){
FiredTriggerRecord rec=lst.get(0);
if(rec.isJobDisallowsConcurrentExecution()){//OLD\u TODO:担心失败/恢复/不稳定的作业状态吗?
返回(STATE_PAUSED.equals(currentState))?STATE_PAUSED_BLOCKED:STATE_BLOCKED;
}
}
返回电流状态;
}捕获(SQLE异常){
抛出新JobPersistenceException(
“无法确定触发器是否应处于阻止状态”
+作业键+“':”
+e.getMessage(),e);
}
}

谢谢@pablosaraiva。这就是我想要的解释。