Skip to content

🌟 Spring Batch 跳过逻辑配置指南

在实际批处理场景中,错误处理策略直接影响作业的健壮性。本教程将详解如何配置跳过逻辑,让您的批处理作业既容错可靠

一、为什么需要跳过逻辑?💡

在批处理作业中,不是所有错误都需导致整个作业失败。合理使用跳过逻辑可以:

1.1 适用场景分析

  • 可跳过场景:供应商列表导入、日志分析等容忍少量数据丢失的场景
  • 不可跳过场景:金融交易处理、医疗数据等要求100%准确的场景
  • 📊 最佳实践:跳过时记录错误日志,便于后续人工核查

TIP

设计原则:跳过策略应由业务专家而非开发人员决定!不同业务场景对数据完整性的要求差异巨大。

二、基础跳过配置 ⚙️

2.1 Kotlin DSL 配置示例

kotlin
@Bean
fun step1(jobRepository: JobRepository, transactionManager: PlatformTransactionManager): Step {
    return StepBuilder("step1", jobRepository)
        .chunk<String, String>(10, transactionManager)  //  // 每10条数据提交一次
        .reader(flatFileItemReader())
        .writer(itemWriter())
        .faultTolerant()  //  // 启用容错机制
        .skipLimit(10)    //  // 最多允许跳过10条记录
        .skip(FlatFileParseException::class.java)  //  // 指定可跳过的异常类型
        .build()
}

关键参数解析:

参数默认值说明
skipLimit()10整个Step允许跳过的最大记录数
skip()指定可跳过的异常类型
chunk()必需定义事务提交间隔

CAUTION

跳过计数规则:第11次跳过会触发作业失败!例如跳过10条记录后,第11条出错将导致Step失败。

2.2 工作流程详解

三、高级异常控制策略 🧩

3.1 排除特定异常类型

kotlin
@Bean
fun advancedStep(jobRepository: JobRepository, transactionManager: PlatformTransactionManager): Step {
    return StepBuilder("step1", jobRepository)
        .chunk<String, String>(10, transactionManager)
        .reader(flatFileItemReader())
        .writer(itemWriter())
        .faultTolerant()
        .skipLimit(10)
        .skip(Exception::class.java)  //  // 跳过所有Exception
        .noSkip(FileNotFoundException::class.java)  //  // 但FileNotFoundException不可跳过
        .build()
}

异常匹配规则:

  1. 当发生FileNotFoundException时:立即失败
  2. 当发生其他Exception时:跳过计数+1 ⚠️
  3. 未声明的异常:默认按致命错误处理 💥

IMPORTANT

继承链匹配原则:Spring Batch使用最近父类匹配规则。例如IOException会匹配到.skip(IOException::class.java)

四、最佳实践与陷阱规避 🛡️

4.1 配置建议

kotlin
.skipLimit(50)
.skip(DataIntegrityViolationException::class)
.skip(FlatFileParseException::class)
.noSkip(IllegalStateException::class)
kotlin
// [!code error:1] // 过于宽泛的跳过策略
.skip(Exception::class)

// [!code warning:2] // 未设置skipLimit
.faultTolerant()
.skip(TimeoutException::class)

4.2 关键注意事项

WARNING

跳过 ≠ 忽略!必须配合监听器记录跳过详情:

kotlin
.listener(object : SkipListenerSupport<Any, Any>() {
    override fun onSkipInRead(t: Throwable) {
        logger.error("跳过读取失败记录", t)  
    }
})

DANGER

事务边界警告:跳过发生在读/处理/写任一阶段,但:

  • 读阶段跳过:不影响事务
  • 写阶段跳过:整个chunk会回滚

五、配置陷阱解析 🧪

5.1 常见错误案例

kotlin
// 错误1:顺序错误导致配置失效
.faultTolerant()
.skip(Exception::class)
.noSkip(IOException::class)  // [!code error] // 此配置将被忽略!

// 正确写法:任意顺序均可
.faultTolerant()
.noSkip(IOException::class)  
.skip(Exception::class)      

5.2 特殊场景处理

处理继承异常的特殊案例
kotlin
// 父类异常配置
.skip(RuntimeException::class)

// 子类异常
class CustomException : RuntimeException()

// 实际运行:
throw CustomException()  // 会被跳过 ✅

六、总结 🏁

配置要素推荐方案避免方案
skipLimit根据数据量设置合理阈值使用默认值10
异常指定明确列出业务可接受异常使用宽泛的Exception
监听器必须实现SkipListener不记录跳过详情
测试模拟各种异常场景仅测试正常流程

NOTE

黄金法则:生产环境部署前,务必测试以下场景:

  1. 达到skipLimit时的行为
  2. 不可跳过异常的处理
  3. 事务回滚是否正确

合理使用跳过逻辑能让您的批处理作业在保持健壮性的同时,最大化数据处理效率! 🚀