我有一个春季批处理作业,可以通过休息URL踢。我想确保只允许一个作业实例运行。如果另一个实例已经运行,那么不要启动另一个即使参数不同。
我搜索并发现任何无法解决方案。考虑扩展SimpleJobLauncher。检查作业的任何实例是否正在运行。
答案 0 :(得分:6)
您可以尝试intercept the job execution,实现JobExecutionListener接口:
public class MyJobExecutionListener extends JobExecutionListener {
//active JobExecution, used as a lock.
private JobExecution _active;
public void beforeJob(JobExecution jobExecution) {
//create a lock
synchronized(jobExecution) {
if(_active!=null && _active.isRunning()) {
jobExecution.stop();
} else {
_active=jobExecution;
}
}
}
public void afterJob(JobExecution jobExecution) {
//release the lock
synchronized(jobExecution) {
if(jobExecution==_active) {
_active=null;
}
}
}
}
然后,注入Job定义:
<job id="myJobConfig">
<listeners>
<listener ref="myListener"/>
</listeners>
</job>
答案 1 :(得分:3)
我通过创建一个JobExecutionListner来解决这个问题,并且在JobExplorer的帮助下,我检查了是否正在运行任何其他实例,如果运行然后停止当前作业。我创建了监听器,以便它可以插入到需要这种场景的任何作业中。
Set<JobExecution> jobExecutions = ((SimpleJobExplorer) jobExplorer.getObject()).findRunningJobExecutions(jobExecution.getJobInstance().getJobName());
if(jobExecutions.size()>1){
Long currentTime = (new Date()).getTime();
for(JobExecution execution : jobExecutions ){
if(execution.getJobInstance().getId().compareTo(jobExecution.getJobInstance().getId())!=0 && (currentTime - execution.getStartTime().getTime()) <lockOverideTime){
jobExecution.stop();
throw new IllegalStateException("Another instance of the job running job name : " +jobExecution.getJobInstance().getJobName() );
}
}
}
答案 2 :(得分:2)
或者,作为对REST URL的响应,如果您的作业使用作业的具体业务规则运行,请使用JobExplorer进行检查
答案 3 :(得分:0)
我认为像下面这样简单的方法可以解决这个问题:
@Autowire
private JobExplorer jobExplorer;
private boolean isJobRunning(Job job) {
Set<JobExecution> jobExecutions = jobExplorer.findRunningJobExecutions(job.getName());
return !jobExecutions.isEmpty();
}
然后,在执行作业之前进行检查:
private void executeJob(Job job, @Nonnull JobParameters params) {
if (isJobRunning(job)) {
return;
}
try {
jobLauncher.run(job, params);
} catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException | JobParametersInvalidException e) {
log.error("could not run job " + jobIdentifier, e);
}
}