为了账号安全,请及时绑定邮箱和手机立即绑定

Quartz作业注解@DisallowConcurrentExecution实现

Quartz作业注解@DisallowConcurrentExecution实现

森栏 2023-08-09 15:12:05
我是石英新手。我发现了@DisallowConcurrentExecutionquartz库提供的注释,文档说:'An annotation that marks a {@link Job} class as one that must not have multiple instances executed concurrently (where instance is based-upon a {@link JobDetail} definition - or in other words based upon a {@link JobKey}).'则DisallowConcurrentExecution.java写为:@Documented@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)public @interface DisallowConcurrentExecution {}但是,我找不到实际处理同一作业不并发执行的实现。这对我来说是新的,所以有人可以帮助我解释内部实现逻辑。我试图查找用法,但只在课堂上找到了它MethodInvokingJobDetailFactoryBean.java
查看完整描述

1 回答

?
泛舟湖上清波郎朗

TA贡献1818条经验 获得超3个赞

我不参与石英项目。我在这里的所有评论都来自我出于好奇而对此事的调查,可能会遗漏一些信息。


首先要知道的是,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);

    }


}


查看完整回答
反对 回复 2023-08-09
  • 1 回答
  • 0 关注
  • 287 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信