当出现异常异常时,如何自动重新启动Spring批处理作业?

当出现异常异常时,如何自动重新启动Spring批处理作业?,spring,spring-batch,Spring,Spring Batch,在提出这个问题之前,我浏览了很多链接,比如:和,但这并没有解决我的问题 我使用的是Spring Boot Batch应用程序,在我的项目中,我有3个作业,每天按计划运行2个下午,晚上以单个方法结束,每个作业都有5个步骤,执行基于块的处理不使用tasklet 我经常看到诸如网络波动、数据库关闭和异常问题之类的问题,spring batch在执行作业时遇到了很多数据丢失问题,因为如果失败,无法从哪里自动重新启动 我希望开发在出现任何类型的异常异常时自动重新启动批处理作业的能力。我们有没有办法做到这一

在提出这个问题之前,我浏览了很多链接,比如:和,但这并没有解决我的问题

我使用的是Spring Boot Batch应用程序,在我的项目中,我有
3个作业
,每天按计划运行
2个下午
,晚上以单个方法结束,每个作业都有
5个步骤
,执行
基于块的处理
不使用
tasklet

我经常看到诸如网络波动、数据库关闭和异常问题之类的问题,spring batch在执行作业时遇到了很多数据丢失问题,因为如果失败,无法从哪里自动重新启动

我希望开发在出现任何类型的异常异常时自动重新启动批处理作业的能力。我们有没有办法做到这一点

我已经像下面那样配置了批处理作业

MyApplication.java

@SpringBootApplication
@EnableBatchProcessing
@EnableScheduling
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}
MyJob.java

@Configuration
public class MyJob {

    @Value("${skip.limit}")
    private Integer skipLimit;

    @Value("${chunk.size}")
    private Integer chunkSize;   

    @Bean(name="myJobCache")
    public CacheManager myJobCache() {
        return new ConcurrentMapCacheManager();
    }

    @Bean("customerJob")
    public Job customerJob(JobBuilderFactory jobBuilderFactory,
            StepBuilderFactory stepBuilderFactory,
            JdbcCursorItemReader<Customer> customerReader,
            JdbcCursorItemReader<Department> departmentReader,
            JdbcCursorItemReader<Stock> stockItemReader,
            JdbcCursorItemReader<Advisory> advisoryItemReder) throws Exception {

        return jobBuilderFactory.get("customerJob")
                .incrementer(new RunIdIncrementer())
                .start(customerStep(stepBuilderFactory, customerReader))
                .next(departmentStep(stepBuilderFactory, departmentReader))
                .next(stackStep(stepBuilderFactory))
                .......
                .......
                .......
                .listener(customerListener())
                .build();
    }

    @Bean
    public Step customerStep(StepBuilderFactory stepBuilderFactory,
            JdbcCursorItemReader<Customer> customerReader) {
        return stepBuilderFactory.get("customerStep").
                <Customer, NewCustomer>chunk(chunkSize)
                .reader(customerReader)
                .processor(customerProcessor())
                .writer(customerWriter())
                .faultTolerant()
                .skip(Exception.class)
                .skipLimit(skipLimit)
                .listener(customerSkipListener())
                .listener(customerStepListener())
                .build();
    }

    @Bean
    public CustomerProcessor customerProcessor() {
        return new CustomerProcessor(myJobCache());
    }
    
    @Bean
    public CustomerWriter customerWriter() {
        return new CustomerWriter();
    }
    
    // Like this all other jobs are configured
}

这可能会有帮助:谢谢,好的信息和您的解决方案将work@MahmoudBenHassine-只是想检查我的作业是否有5个基于块的步骤,如果第3步失败,在重试逻辑的帮助下,它是否会恢复到失败的位置。这可能会有帮助:谢谢,好的信息和您的解决方案将work@MahmoudBenHassine-只是想检查我的作业是否有5个基于块的步骤,如果第3步失败,在重试逻辑的帮助下,它是否会恢复到失败的位置。
public class MyScheduler {

    @Autowired
    private JobLauncher customerJobLauncher;
    
    @Autowired
    private JobLauncher abcJobLauncher;
    
    @Autowired
    private JobLauncher xyzJobLauncher;

    @Autowired
    @Qualifier(value = "customerJob")
    private Job customerJob;
    
    @Autowired
    @Qualifier(value = "abcJob")
    private Job abcJob;
    
    @Autowired
    @Qualifier(value = "xyzJob")
    private Job xyzJob;

    @Scheduled(cron = "0 0 */1 * * *") // run at every hour for testing 
    public void handle() {
        JobParameters params = new JobParametersBuilder()
                .addString("cust.job.id", String.valueOf(System.currentTimeMillis()))
                .addDate("cust.job.date", new Date()).toJobParameters();
        long diff = 0;
        try {
            JobExecution jobExecution = customerJobLauncher.run(customerJob, params);
            Date start = jobExecution.getCreateTime();

            
            JobParameters job2Params = new JobParametersBuilder()
                    .addString("abc.job.id", String.valueOf(System.currentTimeMillis()))
                    .addDate("abc.job.date", new Date()).toJobParameters();
            
            JobExecution job2Execution = abcJobLauncher.run(abcJob, job2Params);            
            
            JobParameters job3Params = new JobParametersBuilder()
                    .addString("xyz.job.id", String.valueOf(System.currentTimeMillis()))
                    .addDate("xyx.job.date", new Date()).toJobParameters();
            
            JobExecution job3Execution = xyzJobLauncher.run(xyzJob, job3Params);
            
            Date end = job3Execution.getEndTime();
            diff = end.getTime() - start.getTime();

            log.info(JobExecutionTimeCalculate.getJobExecutionTime(diff));
        } catch (JobExecutionAlreadyRunningException | JobRestartException | JobInstanceAlreadyCompleteException
                | JobParametersInvalidException e) {
            log.error("Job Failed : " + e.getMessage());
        }
    }
}