使用Quartz,我希望很少有工作(比如大约10个)作为一个链来执行 - 即不兼容。 它们应该在“会计日更改”事件发生后执行但由于它们都访问相同的数据库,我不希望它们一起启动。我希望它们顺序执行(顺序无关紧要)。
我有一个想法将它们放入一个组 - 比如说“account_day_change_jobs”并以某种方式配置Quartz为我做其余的事情:-)手段 - 按顺序运行组中的所有作业。我尝试了API文档(1.8和2.1),试过谷歌但没有找到任何东西。
有可能吗?它甚至合理吗?其他想法如何实现我想要的行为?
非常感谢任何想法:-) 汉斯
答案 0 :(得分:0)
自从我使用石英以来已经很长时间了,但我会尝试两个job listeners注册来听两个不同的组
基本思想是从一个组/列表(“todayGroup”)中激活一个作业,'(“todayGroup”)作业监听器检测完成的好坏。然后开始列表中的下一个工作。但是,它将“刚刚完成”的作业保存在(“tomorrowGroup”)下的调度程序中。
public class MyTodayGroupListener extends JobListenerSupport {
private String name;
private static String GROUP_NAME = "todayGroup";
public MyOtherJobListener(String name) {
this.name = name;
}
public String getName() {
return name;
}
@Override
public void jobWasExecuted(JobExecutionContext context,
JobExecutionException jobException) {
Scheduler sched = context.getScheduler();
// switch the job to the other group so we don't run it again today.
JobDetail current = context.getJobDetail();
JobDetail tomorrows = current.getJobBuilder().withIdentity(current.getKey().getName(), "tomorrow").build();
sched.addJob(tomorrows,true);
//see if there is anything left to run
Set<JobKey> jobKeys = sched.getJobKeys(groupEquals(GROUP_NAME ));
Iterator<JobKey> nextJob = null;
if(jobKeys != null && !jobKeys.isEmpty() ){
nextJob = jobKeys.iterator();
}
if(nextJob != null){
// Define a Trigger that will fire "now" and associate it with the first job from the list
Trigger trigger = newTrigger()
.withIdentity("trigger1", "group1")
.startNow()
.forJob(nextJob =.next())
.build();
// Schedule the trigger
sched.scheduleJob(trigger);
}
}
}
同样地,你需要两个“群组触发器”,它们会在你想要的给定时间从各自的小组中解雇第一份工作。
答案 1 :(得分:0)
下面的Trigger Listener类应重新计划任何尝试执行的作业,而另一个已配置监听器的作业正在运行。 我只是对它进行了轻微的测试,但对于简单的情况,它应该是合适的。
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);
}
}
}
}