Как обновить значение в Quartz JobDataMap? - PullRequest
5 голосов
/ 29 апреля 2011

Я использую кварцевый планировщик 1.8.5. Я создал работу, реализующую StatefulJob. Я планирую работу, используя SimpleTrigger и StdSchedulerFactory.

Похоже, что мне нужно обновить JobDataMap Trigger в дополнение к JobDataMap JobDetail, чтобы изменить JobDataMap из Job. Я пытаюсь понять, почему необходимо обновить оба? Я заметил, что JobDataMap установлен на грязный. Может быть, я должен явно сохранить его или что-то?

Я думаю, мне придется покопаться в исходном коде Кварца, чтобы по-настоящему понять, что здесь происходит, но я решил, что буду ленивым и сначала спрошу. Спасибо за понимание внутренней работы JobDataMap!

Вот моя работа:

public class HelloJob implements StatefulJob {

    public HelloJob() {
    }

    public void execute(JobExecutionContext context)
            throws JobExecutionException {

        int count = context.getMergedJobDataMap().getInt("count");
        int count2 = context.getJobDetail().getJobDataMap().getInt("count");
        //int count3 = context.getTrigger().getJobDataMap().getInt("count");
        System.err.println("HelloJob is executing. Count: '"+count+"', "+count2+"'");

        //The count only gets updated if I updated both the Trigger and 
                // JobDetail DataMaps. If I only update the JobDetail, it doesn't persist. 
        context.getTrigger().getJobDataMap().put("count", count++);
        context.getJobDetail().getJobDataMap().put("count", count++);

        //This has no effect inside the job, but it works outside the job
        try {
            context.getScheduler().addJob(context.getJobDetail(), true);
        } catch (SchedulerException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        //These don't seem to persist between jobs
        //context.put("count", count++);
        //context.getMergedJobDataMap().put("count", count++);
    }
}

Вот как я планирую работу:

try {
    // define the job and tie it to our HelloJob class
    JobDetail job = new JobDetail(JOB_NAME, JOB_GROUP_NAME,
            HelloJob.class);
    job.getJobDataMap().put("count", 1);
    // Trigger the job to run now, and every so often
    Trigger trigger = new SimpleTrigger("myTrigger", "group1",
            SimpleTrigger.REPEAT_INDEFINITELY, howOften);

    // Tell quartz to schedule the job using our trigger
    sched.scheduleJob(job, trigger);
    return job;
} catch (SchedulerException e) {
    throw e;
}

Обновление:

Кажется, мне нужно дважды поместить значение в JobDataMap JobDetail, чтобы оно сохранилось, это работает:

public class HelloJob implements StatefulJob {

    public HelloJob() {
    }

    public void execute(JobExecutionContext context)
            throws JobExecutionException {

        int count = (Integer) context.getMergedJobDataMap().get("count");
        System.err.println("HelloJob is executing. Count: '"+count+"', and is the job stateful? "+context.getJobDetail().isStateful());
        context.getJobDetail().getJobDataMap().put("count", count++);
        context.getJobDetail().getJobDataMap().put("count", count++);
    }
}

Это похоже на ошибку, может быть? Или, может быть, мне не хватает шага, чтобы сказать JobDetail сбросить содержимое его JobDataMap в JobStore?

Ответы [ 4 ]

14 голосов
/ 20 мая 2011

Я думаю, что ваша проблема с использованием оператора postfix ++ - когда вы делаете:

context.getJobDetail().getJobDataMap().put("count", count++);  

вы устанавливаете значение на карте для подсчета и ТО, увеличивая счет.

Для меня это выглядит так, как вы хотели:

context.getJobDetail().getJobDataMap().put("count", ++count);  

, что нужно будет сделать только один раз.

3 голосов
/ 29 апреля 2011

Как вы знаете, в Quartz триггер и задание разделены, а не объединены с некоторыми планировщиками. Они могут позволять вам добавлять в карту данных значения, специфичные для уровня триггера, а не для уровня задания и т. Д.

Я думаю, что это позволяет вам выполнять одно и то же конечное задание с другим набором данных, но при этом иметь некоторые общие данные на уровне задания.

2 голосов
/ 29 апреля 2011

Как ответил scpritch76, задание и триггер являются отдельными, так что может быть много триггеров (расписаний) для данного задания.

Задание может иметь некоторый базовый набор свойств в JobDataMap, и затем триггеры могут предоставлять дополнительные свойства (или переопределять базовые свойства) для конкретных выполнений задания в их JobDataMaps.

0 голосов
/ 06 марта 2017
@PersistJobDataAfterExecution
@DisallowConcurrentExecution
public class DynamicTestJob implements Job
{

    private static final Logger log = LoggerFactory.getLogger(DynamicTestJob.class);

    @Override
    public void execute(final JobExecutionContext context)
    {
        final JobDataMap jobDataMap = context.getJobDetail().getJobDataMap();
        Integer counter = (Integer) jobDataMap.get("counter");

        if (counter == null)
        {
            counter = 1;
        }
        else
        {
            counter++;
        }

        jobDataMap.put("counter", counter);

        System.out.println(counter);
    }

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