You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 04:00:00