我正在使用 quartz 调度器1.8.5。我创建了一个实现StatefulJob的Job。我使用SimpleTrigger和StdSchedulerFactory安排工作。

似乎除了JobDetail的JobDataMap外,我还必须更新触发器的JobDataMap,以便从Job内部更改JobDataMap。我试图了解为什么必须同时更新两者?我注意到JobDataMap设置为脏。也许我必须明确地保存它或其他东西?

我想我必须深入研究Quartz的源代码才能真正理解这里发生的事情,但是我认为我会很懒惰,先问一下。感谢您对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;
}

更新:

似乎我必须将值两次放入JobDetail的JobDataMap中才能使其保持不变,这可行:
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?

最佳答案

我认为您的问题是使用postfix++运算符-执行此操作时:

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

您正在将 map 中的值设置为计数,然后将计数递增。

在我看来,您似乎想要:
context.getJobDetail().getJobDataMap().put("count", ++count);

这只需要做一次。

09-08 08:27