如何配置Spring Batch,使异常时永不重试、直接处理下一项?
Spring Batch Chunk模式下Writer重复调用问题解决方案
问题根源
你遇到的Writer重复调用问题,核心是Spring Batch容错机制的事务回滚重置逻辑导致的:当Writer抛出异常时,默认会触发当前Chunk的事务回滚,回滚过程中会重置ItemReader的状态(比如ListItemReader的指针会退回至Chunk开始前的位置),随后会再次尝试处理该Chunk(即同一个Item),直到重试次数耗尽后才执行跳过逻辑。即使配置了MaxAttemptsRetryPolicy(1)或NeverRetryPolicy,回滚后的状态重置仍会导致Writer被二次调用。
解决方案
要实现「异常后直接处理下一个Item,不再重复调用Writer」,需要禁止异常触发事务回滚,同时保留跳过策略。以下是修改后的配置:
方式一:指定跳过异常类型+禁止回滚
stepBuilder .chunk(1) .reader(new ListItemReader<>(List.of("1", "2", "3"))) .writer(items -> { LOGGER.info("About to write " + items); throw new RuntimeException(); }) .faultTolerant() .skip(RuntimeException.class) // 声明要跳过的异常类型 .skipLimit(Integer.MAX_VALUE) // 设置跳过次数上限(按需调整) .noRollbackFor(RuntimeException.class); // 禁止该异常触发事务回滚
方式二:自定义SkipPolicy+禁止回滚
如果你需要更灵活的跳过判断逻辑,可以保留自定义SkipPolicy:
stepBuilder .chunk(1) .reader(new ListItemReader<>(List.of("1", "2", "3"))) .writer(items -> { LOGGER.info("About to write " + items); throw new RuntimeException(); }) .faultTolerant() .skipPolicy((throwable, skipCount) -> true) .noRollbackFor(RuntimeException.class); // 关键:禁止异常触发回滚
效果验证
修改后日志输出会符合预期:
About to write [1] About to write [2] About to write [3]
内容的提问来源于stack exchange,提问作者realsim
相关产品推荐
相关产品推荐

