Spring batch restrict single instance of job only

℡╲_俬逩灬. 提交于 2019-12-30 06:29:23

问题


I have one spring batch job which can be kicked of by rest URL. I want to make sure only one job instance is allowed to run. and if another instance already running then don't start another. even if the parameters are different.

I searched and found nothing out of box solution. thinking of extending SimpleJobLauncher. to check if any instance of the job running or not.


回答1:


You could try to intercept the job execution, implementing the JobExecutionListener interface:

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; 
              }
          }
    }
}

And then, inject to the Job definition:

<job id="myJobConfig">
    <listeners>
        <listener ref="myListener"/>
    </listeners>
</job>



回答2:


I solved this by creating an JobExecutionListner and with the help of JobExplorer I checked if any other instance is running if running then stop current job.I created listener so that it can be plugged in to any job that requires this kind of scenario.

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() );

                    }
                }

            }



回答3:


Or, in response to REST URL, check using JobExplorer if your job is running using job's specifics business rules




回答4:


I think a simple method like the following might do the trick:

@Autowire
private JobExplorer jobExplorer;

private boolean isJobRunning(Job job) {
    Set<JobExecution> jobExecutions = jobExplorer.findRunningJobExecutions(job.getName());
    return !jobExecutions.isEmpty();
}

Then, prior to executing your job make the check:

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);
    }
}


来源:https://stackoverflow.com/questions/23193779/spring-batch-restrict-single-instance-of-job-only

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!