【问题标题】:Can I set concurrentExecutionDisallowed and persistJobDataAfterExecution on Job instance?我可以在 Job 实例上设置 concurrentExecutionDisallowed 和 persistJobDataAfterExecution 吗?
【发布时间】:2015-04-13 16:30:17
【问题描述】:

是否可以在单个 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。

在我的主要方法中,我从 spring 中获取石英调度程序并加载一个 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 个作业(相同工作和触发器)。

我可以在 Job 或 Trigger 中设置一些属性来实现这一点吗?

谢谢!

【问题讨论】:

    标签: java quartz-scheduler


    【解决方案1】:

    找到了解决我的问题的解决方法。因为我将作业参数和 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 (...) {...}
        ...
      }
    }
    

    希望这可以帮助其他人。

    谢谢。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-07
      • 1970-01-01
      • 1970-01-01
      • 2017-11-30
      • 2018-05-21
      相关资源
      最近更新 更多