我可以在Job实例上设置concurrentExecutionDisallowed和persistJobDataAfterExecution吗?

时间:2015-04-13 16:30:17

标签: java quartz-scheduler

是否可以在单个Job实例上设置concurrentExecutionDisallowed和persistJobDataAfterExecution?

我使用的是Spring 4.1.6.RELEASE,Quartz 2.2.0和JDK 1.8.0u05。

我创建了以下抽象类:

public abstract class AbstractAction extends Action implements Job

其中Action是本地POJO,Job是org.quartz.Job接口。

然后我有一堆AbstractAction的子类,它们在我的spring context.xml中定义为bean。

在我的main方法中,我从spring获取了quartz调度程序并加载了一个DAO方法来获取AbstractAction bean的列表来创建我的预定作业,运行类似于这样的代码:

...
Scheduler scheduler = context.getBean("quartzScheduler", Scheduler.class);
...
for (...)
  ...
  AbstractAction jobBean = context.getBean(actionClass, AbstractAction.class);

  String jobKey = String.valueOf(actionId) + ":"
                + String.valueOf(actionClass) + "["
                + String.valueOf(actionParams) + "]@"
                + String.valueOf(cronExpression);

  JobDetail jobDetail = JobBuilder
    .newJob(jobBean.getClass())
    .withDescription(actionName)
    .withIdentity(jobKey, "scheduler")
    .build();

  JobDataMap jobDataMap = jobDetail.getJobDataMap();
  jobDataMap.put(...);
  ...

  Trigger trigger = TriggerBuilder
    .newTrigger()
    .withDescription("Trigger for " + actionName)
    .withIdentity(jobKey, "scheduler")
    .withSchedule( CronScheduleBuilder.cronSchedule(cronExpression) )
    .startNow()
    .build();

  try {
    scheduler.scheduleJob(jobDetail, trigger);
  } catch (...) {...}
  ...
}
...

基本上,我可以让同一个实现类的多个作业实例使用不同的参数执行(所以不同的作业和触发器,这很好。但是,我不想要一个作业再次执行,如果它仍然在执行(相同的工作和触发器)。

我可以在作业或触发器中设置一些属性来实现吗?

谢谢!

1 个答案:

答案 0 :(得分:0)

找到解决我问题的解决方法。因为我将作业params和cron表达式存储在作业键中,以及我可以从Spring访问我的调度程序这一事实,我在执行的AbstractAction类实现的顶部写了这个:

public abstract class AbstractAction extends Action implements Job {
  private static final Logger LOGGER = LogManager.getLogger();

  protected abstract void preformAction(JobExecutionContext jobContext) throws TerminatingActionException;

  @Override
  public final void execute(JobExecutionContext jobContext) throws JobExecutionException {
    LOGGER.trace(...);
    Scheduler scheduler = context.getBean("quartzScheduler", Scheduler.class);

    try {
      List<JobExecutionContext> executingJobs = scheduler.getCurrentlyExecutingJobs();
      for (JobExecutionContext executingJob : executingJobs) {
        Trigger executingJobTrigger = executingJob.getTrigger();
        Trigger currentJobTrigger = jobContext.getTrigger();
        JobDetail executingJobDetail = executingJob.getJobDetail();
        JobDetail currentJobDetail = jobContext.getJobDetail();
        JobKey executingJobKey = executingJob.getJobDetail().getKey();
        JobKey currentJobKey = jobContext.getJobDetail().getKey();
        String executingFireInstanceId = executingJob.getFireInstanceId();
        String currentFireInstanceId = jobContext.getFireInstanceId();
        if (executingJobTrigger.equals(currentJobTrigger) && executingJobDetail.equals(currentJobDetail) && executingJobKey.equals(currentJobKey) && !(executingFireInstanceId.equals(currentFireInstanceId))) {
          LOGGER.warn("Job " + String.valueOf(currentJobKey) + " is already executing, returning thread control.");
          return;
        }
      }
    } catch (SchedulerException schedulerException) {
      LOGGER.error("Encountered Scheduler Exception while trying to check existing jobs.", schedulerException);
    }
    ...
    try {
      ...
      preformAction(jobContext);
      ...
    } catch (...) {...}
    ...
  }
}

希望这可以帮助其他人。

感谢。