Кварцевая аннотация заданий @DisallowConcurrentExecution Реализация - PullRequest
3 голосов
/ 19 сентября 2019

Я новичок в кварце.Я узнал о @DisallowConcurrentExecution аннотации, предоставленной библиотекой кварца, и документ говорит:

'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 Ответ

2 голосов
/ 27 сентября 2019

Отказ от ответственности: я не участвую в проекте кварца.Все мои комментарии здесь взяты из моего собственного расследования этого из моего собственного любопытства, и некоторая информация может отсутствовать.

Первое, что нужно знать, это то, что 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);
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...