禁止在组范围内并发执行

禁止在组范围内并发执行

本文介绍了Quartz 作业 - 禁止在组范围内并发执行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用 Quartz,我希望很少的工作(比如大约 10 个)作为链执行 - 即不是同时执行.它们应该在会计日更改"事件发生后执行,但由于它们都访问同一个数据库,我不希望它们一起开始.我希望它们按顺序执行(顺序无关紧要).

using Quartz, I'd like few jobs (say about 10) to execute as a chain - i.e. NOT concurrently.They should be executed after an "accounting day change" event occur but since they all access the same DB, I dont want them to start all together. I want them to be executed sequentially instead (order doesnt matter).

我有一个想法,将它们放入一个组中 - 说account_day_change_jobs"并以某种方式配置 Quartz 来为我完成其余的工作:-) 意思是 - 依次运行该组中的所有作业.我尝试了 API 文档(1.8 和 2.1),尝试了谷歌但没有找到任何东西.

I have an idea to put them into a group - say "account_day_change_jobs" and configure Quartz somehow to do the rest for me :-) Means - run sequentially all jobs from the group. I tried the API doc (both 1.8 and 2.1), tried google but didnt find anything.

有可能吗?它甚至合理吗?其他想法如何实现我想要的行为?

Is it possible? Is it even reasonable? Other ideas how to achieve the behavior I want?

非常感谢您的任何想法:-)汉斯

Thanks very much for any ideas :-)Hans

推荐答案

下面的 Trigger Listener 类应该重新安排在另一个已配置侦听器的作业正在运行时尝试执行的任何作业.我只是简单地测试过它,但对于简单的情况,它应该是合适的.

The Trigger Listener class below should re-schedule any jobs that attempt to execute while another job that the listener has been configured for is running.Ive only lightly tested it but for simple cases it should be suitable.

public class SequentialTriggerListener extends TriggerListenerSupport {

private JobKey activeJob;
private Scheduler activeScheduler;
private Queue<JobDetail> queuedJobs = new ConcurrentLinkedQueue<JobDetail>();

public String getName() {
    return "SequentialTriggerListener";
}

public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
    synchronized (this) {
        if (activeJob != null) {
            getLog().debug("Queueing Sequential Job - " + context.getJobDetail().getKey().getName());
            JobDetail jd = context.getJobDetail();
            activeScheduler = context.getScheduler();
            jd = JobBuilder.newJob().usingJobData(jd.getJobDataMap()).withIdentity(getName() + ":" + jd.getKey().getName(), jd.getKey().getGroup())
                    .ofType(jd.getJobClass()).build();
            queuedJobs.add(jd);
            return true;
        } else {
            activeJob = trigger.getJobKey();
            getLog().debug("Executing Job - " + activeJob.getName());
            return false;
        }
    }
}

public void triggerMisfired(Trigger trigger) {
    triggerFinalized(trigger);
}

public void triggerComplete(Trigger trigger, JobExecutionContext context, CompletedExecutionInstruction triggerInstructionCode) {
    triggerFinalized(trigger);
}

protected void triggerFinalized(Trigger trigger) {
    synchronized (this) {
        try {
            if (trigger.getJobKey().equals(activeJob)) {
                getLog().debug("Finalized Sequential Job - " + activeJob.getName());
                activeJob = null;
                JobDetail jd = queuedJobs.poll();
                if (jd != null) {
                    getLog().debug("Triggering Sequential Job - " + jd.getKey().getName());
                    activeScheduler.scheduleJob(jd,TriggerBuilder.newTrigger().forJob(jd).withIdentity("trigger:" + jd.getKey().getName(), jd.getKey().getGroup())
                            .startNow().withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(0).withIntervalInMilliseconds(1)).build());
                }
            } else {
                // this should not occur as the trigger finalizing should be the one we are tracking.
                getLog().warn("Sequential Trigger Listener execution order failer");
            }
        } catch (SchedulerException ex) {
            getLog().warn("Sequential Trigger Listener failure", ex);
        }
    }

}

}

这篇关于Quartz 作业 - 禁止在组范围内并发执行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

07-26 01:05