Quartz 2 文档清楚地设置了 SimpleJobDetail,以便通过设置 concurrent = false 来执行序列化(即下一个作业在当前作业完成后运行)。Quartz 2 文档也清楚地说明了如何设置作业以使用 InvokeMethodJob 调用 spring bean 方法。但不清楚的是如何将 InvokeMethodJob 设置为仅运行序列化 (concurrent=false)。我在 conf/Config.groovy 中像这样设置 InvokeMethodJob:
import static org.quartz.JobBuilder.*
import static org.quartz.SimpleScheduleBuilder.*
import static org.quartz.TriggerBuilder.*
import org.quartz.impl.triggers.*
import org.quartz.JobDataMap
import org.quartz.JobDetail
import org.quartz.Trigger
import grails.plugin.quartz2.InvokeMethodJob
//Begin quartz configuration
grails.plugin.quartz2.autoStartup = true
org{
quartz{
scheduler.instanceName = 'MyScheduler'
threadPool.class = 'org.quartz.simpl.SimpleThreadPool'
threadPool.threadCount = 20
threadPool.threadsInheritContextClassLoaderOfInitializingThread = true
jobStore.class = 'org.quartz.simpl.RAMJobStore'
}
}
grails.plugin.quartz2.jobSetup.mySchedule = { quartzScheduler, ctx ->
def props = new JobDataMap([concurrent:false,targetObject:ctx.myActionService,targetMethod:'myaction',arguments:[true]])
JobDetail jobDetail = newJob(InvokeMethodJob.class)
.withIdentity("perform my action")
.usingJobData(props)
.build()
Trigger trigger = newTrigger().withIdentity("every 90 seconds trigger")
.withSchedule(
simpleSchedule().withIntervalInSeconds(90).repeatForever()
)
.startNow().build()
quartzScheduler.scheduleJob(jobDetail, trigger)
}
但是,这将允许多个线程同时执行 myActionService.myaction() 调用。我希望调度程序停止对它的进一步调用,直到第一个调用返回。
我阅读了有关@DisallowConcurrentExecution 的信息,但没有办法在conf/Config.groovy 的定义中应用它(或如何应用它的示例)。
我可以设计的最佳解决方案是创建一个新的 Groovy 类扩展 InvokeMethodJob 并使用 @DisallowConcurrentExecution 进行注释,如下所示:
package com.fourgablesguy.quartz2
import grails.plugin.quartz2.InvokeMethodJob
import org.quartz.DisallowConcurrentExecution
/**
* InvokeMethodJob that is not concurrently executed, serial execution
* this has the DisallowConcurrentExecution annotation
*/
@DisallowConcurrentExecution
class SerializedInvokeMethodJob extends InvokeMethodJob { }
然后更改 conf/Config.groovy 以使用这个新的 Job 类类型:
import com.fourgablesguy.quartz2.SerializedInvokeMethodJob
...
JobDetail jobDetail = newJob(SerializedInvokeMethodJob.class)
但是我可能错过了一些不太复杂的事情,可以使用石英 2 来完成相同的任务,所以如果有人有不同的解决方案,我会发布这个。