Spring Batch跳过异常但重复执行Chunk问题排查
问题原因及解决方案
核心原因
Spring Batch开启faultTolerant()后,默认对所有可跳过的异常会执行1次重试——加上首次执行,就会出现总共两次的Chunk执行。即使移除显式的retry和retryLimit配置,这个默认重试逻辑依然生效,因为skip机制的底层依赖重试流程来判定是否触发跳过:当异常抛出时,框架会先重试一次,确认异常无法恢复后才会执行跳过操作。
另外,Chunk本身是事务边界,首次执行抛出可跳过异常时,当前事务会回滚,框架会重新读取该Chunk的全部数据再次执行,这也会让你感知到“Chunk重复执行两次”。
解决办法
需要显式关闭非目标异常的重试行为,只保留对DataNotFoundException的重试配置。修改后的配置代码如下:
@JobScope @Bean public Step batchUpdateStep(JobRepository jobRepository, PlatformTransactionManager transactionManager, @Qualifier("batchUpdateItemWriter") ItemWriter<UpdateRequest> batchUpdateItemWriter, @Qualifier("batchUpdateItemProcessor") ItemProcessor<UpdateDto, UpdateRequest> batchUpdateItemProcessor) { return new StepBuilder("batch-update-step", jobRepository) .<UpdateDto, UpdateRequest>chunk(batchUpdateChunkSize, transactionManager) .reader(batchUpdateItemReader(null)) .processor(batchUpdateItemProcessor) .writer(batchUpdateItemWriter) .faultTolerant() .skipLimit(Integer.MAX_VALUE) .skip(Exception.class) .noSkip(DataNotFoundException.class) // 显式关闭其他异常的重试,仅保留DataNotFoundException的重试逻辑 .noRetry(Exception.class) .retryLimit(3) .retry(DataNotFoundException.class) .listener(getBatchUpdateStepListener()) .listener(getBatchUpdateSkipListener(null, null)) .listener(batchUpdateProcessListener(null, null)) .build(); }
这样配置后,除DataNotFoundException会按预期重试3次外,其他可跳过的异常会直接触发跳过逻辑,不会出现两次执行的情况。
内容的提问来源于stack exchange,提问作者Vinod
相关产品推荐
相关产品推荐

