【问题标题】:Quartz @DisallowConcurrentExecution to allow more than one instance of the class to run but not the job?Quartz @DisallowConcurrentExecution 允许多个类的实例运行但不允许作业?
【发布时间】:2012-06-27 09:42:27
【问题描述】:

我一直在研究一个调度引擎,它从数据库中读取调度作业并安排它们工作正常,但是数据库中的行只是某些类型作业的“配置”,例如:

获取 FTP 的特定配置具有

host: imagineryHost1.com 
post: 22

和另一个同班有

host: imagineryHost2.com
post: 21

我们使用自己的触发器和自己的单独数据创建两个 FPTjob。

/**
BaseJob is an Abstract class extending QuartzJobBean used to handle our logging and 
other requirements that need across all our jobs.
*/
public class FTPJob extends BaseJob {

    /**
        Called from executeInternal of QuartzJobBean 
    */
    @Override
    public boolean execute1V(JobExecutionContext context) {
        //Code to get Files from FTP.
    }
}

这些是使用带有 cron 的 TriggerBuilder 安排的。

如果我添加 @DisallowConcurrentExecution 将只允许我们的 FTPJob 的 1 个实例在任何时候运行,但是我需要能够运行 FTPJob 的多个实例,但仅限于该特定配置的一个实例类。

任何有关如何进步的线索都将受到高度赞赏:)

更新

根据 ftom2 的回答,我去挖掘并找到了 TriggerListener,因为每个作业配置都有自己的唯一 ID,因此我可以“否决”运行 ie 的作业。

public boolean vetoJobExecution(Trigger trigger, JobExecutionContext context) {
    try {
        Iterator<JobExecutionContext> it =     
        context.getScheduler().getCurrentlyExecutingJobs().iterator();

        boolean found = false;
        while(it.hasNext()) {
            JobExecutionContext job = it.next();

            if(trigger.getJobKey().equals(job.getJobDetail().getKey())) {
                return false;
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

有没有其他更内置的方法来处理这个问题?

【问题讨论】:

    标签: java spring quartz-scheduler


    【解决方案1】:

    我不确定这是否可能,但这可能是一个方向。

    您可以实现JobListener,然后执行以下操作:

    1. 使用 jobWasExecuted,您将在 jobDetails 中设置一个标志,表明该作业已完成。
    2. 使用 jobToBeExecuted,您将在它启动之前检查作业状态,看看它是否处于运行状态,如果是 - 停止它(参见 here),如果不是 - 让它运行并将其状态设置为运行。李>

    希望这会有所帮助。

    【讨论】:

    • 感谢您的回答,这让我想到了我添加到问题的更新,可能出现的一个问题是需要数据持久性才能维护您的标志,但这可能会奏效。我将在剩下的时间里保持开放状态,看看是否有其他人找到替代解决方案,如果没有,我会将其标记为答案:)
    • jobDetails是用来持久化数据的,你还不够吗?
    • 通过 JobDetails 我假设您的意思是在其中设置 JobDataMap 中的值,但是除非您设置 PersistJobDataAfterExecution,否则不会记录放回该地图的任何内容,我唯一的观点是在某些情况下可能不可取:)
    【解决方案2】:

    很抱歉迟到了一年……但是建议使用 TriggerLinstener 不是非线程安全的吗?在我看来,两个工作可以在 getCurrentlyExecutingJobs() 返回之前通过否决阶段。在同样的情况下,我在调度程序上使用了执行锁,它甚至更少“内置”......(想法是 - 尝试在触发器 linstener 中获取锁,如果不能,则否决,从作业侦听器 jobWasExecuted 返回锁)。

    【讨论】:

      【解决方案3】:

      貌似有状态的job是不允许并发执行的,你可以简单实现StatefulJob而不是Job接口

      【讨论】:

      • 感谢您的回答,但是虽然该作业的特定实例(数据相同)不能运行两次,但类本身的实例可以假设数据不同。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多