Spring Batch 容错机制分析
Chunk 事务边界
Spring Batch 会在 每个 chunk 的处理周期 开始时开启一个事务。
这个事务覆盖 读 → 处理 → 写 的整个过程。
当
ItemWriter.write()
执行完成后,事务才会提交。
Retry 成功的情况
- 流程:
- 当
ItemReader
或ItemWriter
抛出异常时,如果配置了.retry(Exception.class)
,Spring Batch 会在同一个 chunk 的事务上下文里对该条记录进行重试。 - 如果在重试次数限制内 最终成功,那么这个 chunk 会继续执行,最后事务会 正常提交。
- 当
- 事务结果:
- 不会回滚,因为最终是成功的。
- 之前的失败尝试只是在内存和日志层面记录,不会导致事务提交或回滚。
👉 换句话说:Retry 成功 = 事务继续,最终提交。
Skip 的情况
Skip 生效时:
如果异常在允许的 skip 范围内(未超过 skipLimit),Spring Batch 会“丢掉”这条坏数据,但 整个 chunk 的事务依然提交。
这样保证了其他正常数据不会丢失。
SkipLimit 超过时:
一旦跳过次数超过 skipLimit,Spring Batch 会认为 Step 失败。
当前正在执行的 chunk 事务会 回滚,因为它没能成功完成。
Step 状态会标记为 FAILED,Job 是否失败取决于后续配置(比如
allowStartIfComplete
、Job flow
的on("FAILED")
分支等)。
⚖️ 总结对比
情况 | 行为 | 事务结果 |
---|---|---|
Retry 成功 | 重试后成功,继续执行 | 事务正常提交 |
Retry 失败 + Skip(未超限) | 记录失败数据,跳过继续 | 事务提交(跳过的数据不写出) |
Retry 失败 + Skip(超限) | Step 失败 | 整个 chunk 回滚,job 可能失败 |
Retry 失败 + 未配置 Skip | Step 失败 | 整个 chunk 回滚 |
✅ 最佳实践
- Retry 用于处理临时性错误(如网络抖动、死锁)。
- Skip 用于处理“坏数据”或不可恢复的异常(如格式错误、违反约束)。
- 两者结合使用,可以保证批处理既 健壮(不会因为个别坏数据中断),又 可靠(临时错误能自动恢复)。