当前位置: 首页 > 面试题库 >

石英:在Jobs.xml中阻止作业的并发实例

韦业
2023-03-14
问题内容

这应该真的很容易。我使用的是在Apache Tomcat
6.0.18下运行的Quartz,我有一个jobs.xml文件,该文件设置了每分钟运行的计划作业。

我想做的是,如果下一个触发时间到来时该作业仍在运行,则我不想启动新作业,因此可以让旧实例完成。

有没有办法在Jobs.xml中指定此设置(防止并发实例)?

如果不是,是否可以共享我的应用程序Job实现中对内存中单例的访问(这是通过JobExecutionContext吗?),以便我自己处理并发性?(并检测以前的实例是否正在运行)

更新: 在文档中苦苦挣扎之后,我正在考虑以下两种方法,但是要么不知道如何使它们工作,要么有问题。

  1. 使用StatefulJob。这样可以防止并发访问…但是我不确定如果使用它,还会产生其他副作用,我也想避免以下情况:

假设触发时间是每分钟,即触发#0 =在时间0,触发#1 = 60000msec,触发#2 = 120000,#3 =
180000,依此类推,触发在时间0的触发#0触发了我的工作,耗时130000msec。对于普通作业,它将在作业触发器#0仍在运行时执行触发器#1和#2。使用StatefulJob,它将在#0在130000之后完成后立即执行触发器#1和#2。我不希望那样,我不希望#1和#2运行,而下一个运行作业的触发器应该发生在#3(180000msec)。因此,我仍然必须对StatefulJob进行其他操作才能使其按我想要的方式工作,因此使用它并没有太大优势。

  1. 使用TriggerListener从vetoJobExecution()返回true。

尽管实现接口似乎很简单,但我必须弄清楚如何以声明方式设置一个TriggerListenerhtml" target="_blank">实例。
3. 使用static实现Job的类拥有的共享线程安全对象(例如,信号量或其他)。

我不喜欢通过staticTomcat /
Quartz下的关键字使用单例的想法,不确定是否有副作用。另外,我真的不希望它们成为真正的单例,而只是与特定工作定义相关联的东西。

  1. 实现我自己的触发器,该触发器扩展了SimpleTrigger并包含可以运行自己的TriggerListener的共享状态。

同样,我不知道如何设置XML文件以使用此触发器而不是使用standard
<trigger><simple>...</simple></trigger>


问题答案:

当您的Quartz作业唤醒时,您可以执行以下操作:

JobDetail existingJobDetail = sched.getJobDetail(jobName, jobGroup);
    if (existingJobDetail != null) {
        List<JobExecutionContext> currentlyExecutingJobs = (List<JobExecutionContext>) sched.getCurrentlyExecutingJobs();
        for (JobExecutionContext jec : currentlyExecutingJobs) {
            if(existingJobDetail.equals(jec.getJobDetail())) {
                //String message = jobName + " is already running.";
                //log.info(message);
                //throw new JobExecutionException(message,false);
            }
        }
        //sched.deleteJob(jobName, jobGroup); if you want to delete the scheduled but not-currently-running job
    }


 类似资料:
  • 我有一个Sprint Boot-Java8应用程序,它有一个quartz作业,我在启动时配置该作业并设置一个时间表。该作业按照计划自动运行,这与您对quartz作业的期望一样。然而,现在我希望能够允许用户通过点击前端上的一个按钮手动触发这些作业,而不会扰乱该作业的正常调度。这是我所有的相关档案。 但每次运行应用程序并点击控制器的方法时,都会在控制台中出现以下错误: 我到底做错了什么?如何使此作业按

  • 我们使用Quartz 2.1.6在集群上进行作业调度,并将作业数据存储在我们的MySQL数据库(MySQL5.1)中的JDBC jobstore中。 我们所有的Quartz配置(调度器、作业、触发器)都是在Spring启动时完成的。我们将数据存储在数据库中以用于聚类目的。

  • 将库升级到和(查找FTP库中可能的bug)我设法持续了3周 我有一个要监视,该作业表示触发器状态为。应用程序服务器不重用阻塞进程的 我没有找到关于Quartz这类问题的文档,因此我怀疑是FTP库中的bug干扰了Quartz启动的线程,例如的使用

  • 我很难让Grails中的Quartz工作按预期同时运行。这就是我的工作。我已经注释掉了使用Executor插件的代码行,但是当我没有注释掉它们时,我的代码会按预期工作。 就我而言,myService2。doOtherStuff()需要很长时间才能完成,这与下一次触发此作业的时间重叠。我不介意它们是否重叠,这就是我明确添加def concurrent=true的原因,但它不起作用。 我有Quartz

  • 是否可以添加/删除/修改在Quartz Spring Boot中动态安排的作业(在运行时),由使用我的门户的最终用户。由于计划无法从外部访问,我不知道有什么办法。基本上,我需要将所有的时间表信息存储到数据库中并访问它们。Im构建的门户将被大量用户使用,实现这一目标的正确解决方案是什么? 否则我可以像下面这样使用cron吗 每5 mns扫描一次作业以实现此目的。