How to make a Spring Batch step depends on previous step?

4.1k views Asked by At

I am using Spring Batch to read some data from CSV files and put it in a database. My Batch job must be compound of 2 steps :

  1. Check files (names, extension, content ..)
  2. Read lines from CSV and save them in DB (ItemReader, ItemProcessor, ItemWriter..)

Step 2 must not be executed if Step 1 generated an error (files are not conform, files doesn't exist ...)

FYI, I am using Spring Batch without XML configuration ! Only annotations : Here's what my job config class looks like :

@Configuration
@EnableBatchProcessing
public class ProductionOutConfig {

    @Autowired
    private StepBuilderFactory steps;

    @Autowired
    private JobBuilderFactory jobBuilderFactory;


    @Autowired
    private ProductionOutTasklet productionOutTasklet;

    @Autowired
    private CheckFilesForProdTasklet checkFilesForProdTasklet;

    @Bean
    public Job productionOutJob(@Qualifier("productionOut")Step productionOutStep,
                                @Qualifier("checkFilesForProd") Step checkFilesForProd){
        return jobBuilderFactory.get("productionOutJob").start(checkFilesForProd).next(productionOutStep).build();
    }

    @Bean(name="productionOut")
    public Step productionOutStep(){
        return steps.get("productionOut").
                tasklet(productionOutTasklet)
                .build();}

    @Bean(name = "checkFilesForProd")
    public Step checkFilesForProd(){
        return steps.get("checkFilesForProd")
                .tasklet(checkFilesForProdTasklet)
                .build();
    }
}
2

There are 2 answers

0
Sabir Khan On BEST ANSWER

What you are looking for is already the default behavior of Spring Batch i.e. next step wouldn't be executed if previous step has failed. To mark current step as failed step, you need to throw a run time exception which is not caught.

If exception is not handled, spring batch will mark that step as failed and next step wouldn't be executed. So all you need to do is to throw an exception on your failed scenarios.

For complicated job flows , you might like to use - JobExecutionDecider , Programmatic Flow Decisions

4
mabad On

As the documentation specifies you can use the method "on" which starts a transition to a new state if the exit status from the previous state matches the given pattern.

Your code could be similar to something like this :

    return jobBuilderFactory.get("productionOutJob")
           .start(checkFilesForProd)
           .on(ExitStatus.FAILED.getExitCode()).end()
           .from(checkFilesForProd)
           .on("*")
           .to(productionOutStep)
           .build();