【问题标题】:How to prevent concurrent execution of a job in Grails?如何防止在 Grails 中并发执行作业?
【发布时间】:2011-06-23 12:14:47
【问题描述】:

我在 grails 中有一个石英作业,需要每 5 秒执行一次,但我需要按顺序执行。在某些情况下,作业的执行超过了这 5s,在这种情况下,我不想在之前的执行未完成时执行。如何在 grails 中进行配置?

(当然整个魔法都可以用一个静态的 volatile 标志来完成,但这不是一种非常优雅的方式) (另外我怎样才能将作业配置为单例?)

谢谢

【问题讨论】:

    标签: grails quartz-scheduler


    【解决方案1】:

    假设您使用的是 grails 石英插件,您应该能够将作业类的 concurrent 属性设置为 false

    来自Quartz Plugin Documentation

    “默认情况下,作业以并发方式执行,因此即使之前执行的同一作业仍在运行,新作业也可以开始执行。如果您想覆盖此行为,您可以使用“并发”属性,在本例中为 Quartz 的将使用 StatefulJob”

    在最新版本的石英插件(Grails 3.3.* 的 2.0.13 版)中,看起来像这样:

    class MyJob {
    
        static concurrent = false
    
        void execute() {
            println "Job run!"
        }
    }
    

    对于旧版本的 grails/quartz,它看起来很相似,但属性设置为 def 而不是 static

    class MyJob {
    
        def concurrent = false
    
        void execute() {
            println "Job run!"
        }
    }
    

    【讨论】:

    • 是的,这就是解决方案。但是我认为这并不能阻止任务不断累积到队列中......
    • 那么如何防止任务队列一直增长直到OutOfMemory发生?
    • 通常您希望任务排队,当任务是“计数”或“逐步”类型的任务时,一个长任务不应阻止其他任务的执行。如果这确实是一个问题,那么 Quartz 可能不是您想要的,您想要的是一个不断循环运行的线程。如果您需要限制它,您可以将 Thread.sleep(remainingTime) 延迟。
    • @BillK 我认为这不是一个好主意,因为您将永远占用线程。
    • 在您上次编辑时,您犯了一个小的复制和粘贴错误。在第二个代码示例中(对于 OLD 石英/grails 版本)它应该是 def concurrent = false
    【解决方案2】:

    【讨论】:

    • 这很好,但这些解决方案在 Grails 环境中不起作用。
    • 我的意思是我无法配置它。
    【解决方案3】:

    对于基于 Quartz 的作业,并发是使用

    实现的
    static concurrent = false
    

    在工作类中。

    请注意定义中的 static,至少从 2.0.12 版开始,需要它而不是 def concurrent = false。 请参阅Quartz documentation

    【讨论】:

      【解决方案4】:

      我在没有石英的情况下使用 spring 任务实现了它:

      beans = { 
          xmlns task: "http://www.springframework.org/schema/task"
      
          task.'scheduler'('id':"myScheduler", 'pool-size':"1")
      
          task.'scheduled-tasks'('scheduler':"myScheduler") {
              task.'scheduled'(ref:"myBean", method:"myBeanMethodToExec", 'fixed-delay':5000)
          }
      }
      

      (pool-size 1 我认为甚至没有必要,但要确保 100% ;))

      【讨论】:

      • 您提出了一个问题,然后选择了一个未解决该问题的答案。无论您最终使用什么,这都不是解决您提出的问题的最佳答案。
      • 是的,你是对的,虽然我写了“他不会阻止任务不断累积到队列中”——我想到了这种方法,实际上这已经用这个 spring 调度程序解决了。但你是对的,这是对我问题的一个很好的回答。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-01-13
      • 2012-05-20
      相关资源
      最近更新 更多