What is the function of JobBuilderFactory.get(job).incrementer(RunIdIncrementer)?

13,691

This isn't a "Boot thing" as much as it is a "Batch thing". Spring Batch has the rule that a JobInstance can only be run once to completion. This means that for each combination of identifying job parameters, you can only have one JobExecution that results in COMPLETE. A RunIdIncrementer will append an additional, unique parameter to the list of parameters so that the resulting combination would be unique...giving you a new JobInstance each time you ran the job with the same combination of identifying parameters.

The RunIdIncrementer is really just a special case of the JobParametersIncrementer which you can read more about in our documentation here: http://docs.spring.io/spring-batch/trunk/reference/htmlsingle/#JobParametersIncrementer

Share:
13,691
LumberSzquatch
Author by

LumberSzquatch

LinkedIn page

Updated on July 17, 2022

Comments

  • LumberSzquatch
    LumberSzquatch almost 2 years

    I'm developing a Spring-Batch project using Spring-Boot and everything is going along nicely. I've done a few spring-batch examples (including some from spring.io), but I'm not sure what some of the stuff does, and "it just works" doesn't satiate me.

    My spring boot main class implements CommandLineRunner and for this particular job the initial set up looked like

    @Bean
    public Job myJob(JobExecutionListenerSupport listener) {
        return myJobBuilderFactory.get(JOB)
                .listener(listener)
                .start(myStep())
                .build();
    }
    

    Which caused

    java.lang.IllegalStateException: Failed to execute CommandLineRunner
        at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:809) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
        at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:790) ~[spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
        at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:777) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:308) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1191) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1180) [spring-boot-1.3.2.RELEASE.jar:1.3.2.RELEASE]
        at org.bjc.providermodel.maintenance.MaintenanceApplication.main(MaintenanceApplication.java:20) [classes/:?]
    Caused by: org.springframework.batch.core.repository.JobExecutionAlreadyRunningException: A job execution for this job is already running: JobInstance: id=99, version=0, Job=[myJob]
    

    Why does changing the above bean to

    @Bean
    public Job myJob(JobExecutionListenerSupport listener) {
        return myJobBuilderFactory.get(JOB)
                .incrementer(new RunIdIncrementer())
                .listener(listener)
                .start(myStep())
                .build();
    }
    

    Make everything go smoothly? I attempted to read up on the doc for RunIdIncrementer and also read up a little here. From what I can tell it needs this incrementer to keep track of a particular set of jobs that are running to do "stuff", but not sure what stuff is exactly. The Spring-Boot abstraction is making it hard for me to know what's going on here

  • suiwenfeng
    suiwenfeng almost 6 years
    Thanks, saved my day.