Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring batch restrict single instance of job only

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.

like image 431
sandeep Avatar asked Jan 27 '26 10:01

sandeep


2 Answers

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>
like image 65
Tomas Narros Avatar answered Jan 29 '26 23:01

Tomas Narros


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

                    }
                }

            }
like image 20
sandeep Avatar answered Jan 29 '26 23:01

sandeep



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!