简体   繁体   中英

Is there a bug in Spring Batch Step flow function?

In the below piece of code, when StepA fails only StepB and StepC should execute but what actually happens is that all the 3 steps are getting executed! I want to split a spring batch job depending upon whether a step passes or not. I know that there are other ways of doing this by using JobDecider, setting some job parameter, etc but I wanted to know I was doing wrongly here?

@Configuration
@EnableBatchProcessing
public class JobConfig {

    @Autowired
    private JobBuilderFactory jobBuilderFactory;

    @Autowired
    private StepBuilderFactory stepBuilderFactory;

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new ResourcelessTransactionManager();
    }

    @Bean
    public JobRepository jobRepository() {
        try {
            return new MapJobRepositoryFactoryBean(transactionManager())
                    .getJobRepository();
        } catch (Exception e) {
            return null;
        }
    }

    @Bean
    public JobLauncher jobLauncher() {
        final SimpleJobLauncher launcher = new SimpleJobLauncher();
        launcher.setJobRepository(jobRepository());
        return launcher;
    }

    @Bean
    public Job job() {
        return jobBuilderFactory.get("job").
                flow(stepA()).on("FAILED").to(stepC()).next(stepD()).
                from(stepA()).on("*").to(stepB()).next(stepC()).end().build();
    }

    @Bean
    public Step stepA() {
        return stepBuilderFactory.get("stepA")
                .tasklet(new RandomFailTasket("stepA")).build();
    }

    @Bean
    public Step stepB() {
        return stepBuilderFactory.get("stepB")
                .tasklet(new PrintTextTasklet("stepB")).build();
    }

    @Bean
    public Step stepC() {
        return stepBuilderFactory.get("stepC")
                .tasklet(new PrintTextTasklet("stepC")).build();
    }

    @Bean
    public Step stepD() {
        return stepBuilderFactory.get("stepD")
                .tasklet(new PrintTextTasklet("stepD")).build();
    }

    @SuppressWarnings("resource")
    public static void main(String[] args) {
        // create spring application context
        final ApplicationContext appContext = new AnnotationConfigApplicationContext(
                JobConfig.class);
        // get the job config bean (i.e this bean)
        final JobConfig jobConfig = appContext.getBean(JobConfig.class);
        // get the job launcher
        JobLauncher launcher = jobConfig.jobLauncher();
        try {
            // launch the job
            JobExecution execution = launcher.run(jobConfig.job(), new JobParameters());
            System.out.println(execution.getJobInstance().toString());
        } catch (JobExecutionAlreadyRunningException e) {
            e.printStackTrace();
        } catch (JobRestartException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JobInstanceAlreadyCompleteException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (JobParametersInvalidException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

StepA: is a dummy job which fails ie it throws some exception public class RandomFailTasket extends PrintTextTasklet {

    public RandomFailTasket(String text) {
        super(text);
    }

    public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
            throws Exception {

        if (Math.random() < 0.5){
            throw new Exception("fail");
        }
        return RepeatStatus.FINISHED;
    }

}

StepB, StepC, StepD are also dummy tasklets: public class PrintTextTasklet implements Tasklet {

    private final String text;

    public PrintTextTasklet(String text){
        this.text = text;
    }


    public RepeatStatus execute(StepContribution arg0, ChunkContext arg1)
            throws Exception {
        System.out.println(text);
        return RepeatStatus.FINISHED;
    }

}

need to have a look at the xml structure that you are using.

Try using Step listener - and then in the after step method you can check the Step status and then you can implement your logic to call the next step or not

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM