0

我有一个应用程序有几个不同的、长期运行的石英作业。每个作业都由一种事件(例如用户操作)触发,并且每个此类事件仅运行一次。在应用程序工作的环境中,会发生以下情况......

  1. 应用程序正在运行,
  2. 长时间运行的作业被触发,
  3. 在作业执行期间发生应用程序关闭,
  4. 应用程序再次启动。

是否有可能导致石英会自动重新启动之前已启动但未完成的作业(在应用程序的上一个会话中)?我的意思是使用 jdbc 作业存储,它适用于未完成的作业 - 但是否可以重新启动未完成的作业。

4

1 回答 1

0

这是我发现的最好的方法:

  1. 配置石英调度器:

    org.quartz.scheduler.interruptJobsOnShutdownWithWait=true

  2. 使您的可恢复作业实现 InterruptableJob,并手动触发当前作业作为中断逻辑的一部分(示例如下)。
  3. 编写自己的 ShutdownHook 来调用 Scheduler.shutdown(true) 或使用石英 ShutdownHookPlugin

这样,当 VM 检测到有序关闭时(硬关闭由 RequestRecovery: quartz jobDetail requestRecovery处理),实现 InterruptableJob 的作业将被中断并重新触发。直到下一次启动才会发生此触发器。

有一个如何实现的快速示例:

public static class TriggerOnInterruptJob implements InterruptableJob {
    private boolean interrupt = false;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {
        LOGGER.debug("START");
        synchronized (mutex) {
            mutex.notifyAll();
        }
        executionCount.incrementAndGet();
        try {
            while (!interrupt)
                Thread.sleep(5000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        try {
            context.getScheduler().triggerJob(context.getJobDetail().getKey());
        } catch (SchedulerException e) {
            e.printStackTrace();
        }

    }

    @Override
    public void interrupt() throws UnableToInterruptJobException {
        interrupt = true;

    }

}
于 2014-04-24T17:04:51.160 回答