Step 配置
本章定位:全面掌握
StepBuilderAPI——从基础 Chunk/Tasklet 配置到高级容错策略、监听器注册和事务控制的完整配置能力。
定义与作用
Step 配置是将数据处理逻辑和运行策略声明式组合的过程。通过 StepBuilder 的流式 API,开发者无需手动编写循环、事务和状态管理代码。
小崔对 StepBuilder 的理解:
"StepBuilder 就像一份'施工方案':Chunk(50) 是批量大小,reader() 是原料来源,processor() 是加工工序,writer() 是成品入库。faultTolerant() 是应急预案——允许哪些情况跳过、哪些情况重试。"
核心原理
StepBuilder API 层级结构
完整示例
场景一:飞翔科技——完整的容错 Step 配置
背景:运营部杨英的订单导入 Step 需要处理 CSV 格式错误、数据库瞬时故障等异常。小崔配置了完整的容错策略。
@Bean
public Step robustOrderImportStep(JobRepository jobRepository,
PlatformTransactionManager tx,
FlatFileItemReader<Order> reader,
ItemProcessor<Order, OrderEntity> processor,
JdbcBatchItemWriter<OrderEntity> writer,
ItemReadListener<Order> readListener,
SkipListener<Order, OrderEntity> skipListener) {
return new StepBuilder("robustOrderImportStep", jobRepository)
.<Order, OrderEntity>chunk(50, tx)
.reader(reader)
.processor(processor)
.writer(writer)
// === 容错配置 ===
.faultTolerant()
.skip(FlatFileParseException.class) // CSV 格式错误 → 跳过
.skip(DataIntegrityViolationException.class) // 约束冲突 → 跳过
.skipLimit(100) // 最多跳过 100 条
.retry(TransientDataAccessException.class) // 瞬时 DB 故障 → 重试
.retryLimit(3) // 最多重试 3 次
.noRollback(ValidationException.class) // 校验异常不回滚事务
// === 监听器 ===
.listener(readListener) // 读监听器(记录每行读取)
.listener(skipListener) // 跳过监听器(记录跳过的数据)
// === 事务 ===
.transactionManager(tx)
.build();
}
场景二:高性能 Step 配置
@Bean
public Step highPerformanceStep(JobRepository jobRepository,
PlatformTransactionManager tx,
ItemReader<Order> reader,
ItemWriter<Order> writer) {
return new StepBuilder("highPerformanceStep", jobRepository)
.<Order, Order>chunk(500, tx) // 大 Chunk 减少事务次数
.reader(reader)
.writer(writer) // 无 Processor,直接透传
.throttleLimit(10) // 限制并发资源使用
.build();
}
操作前后对比:
| 配置维度 | 基础配置 | 优化后配置 | 效果 |
|---|---|---|---|
| Chunk Size | 10 | 500 | 事务数减少 50 倍 |
| Processor | 有(每条 5ms) | 无 | 减少 CPU 开销 |
| throttleLimit | 默认 4 | 10 | 提高并发资源利用率 |
| 预期吞吐 | ~1000/s | ~50000/s | 50 倍提升 |
易错场景与避坑
反例一:faultTolerant() 后忘配 skipLimit
// ❌ 开启了容错但没设上限 → 默认 skipLimit=0 → 任何跳过都会失败
return new StepBuilder("step", jobRepository)
.<Order, Order>chunk(50, tx)
.reader(reader)
.writer(writer)
.faultTolerant()
.skip(FlatFileParseException.class)
// 忘记 .skipLimit() → 等效于 skipLimit=0
.build();
反例二:noRollback 用错异常类型
// ❌ noRollback 配置了不可跳过的异常 → Chunk 仍然回滚
.faultTolerant()
.noRollback(NullPointerException.class) // NPE 不应被 noRollback——这是代码 bug!
正确做法:noRollback 只应用于预期的业务异常(如 ValidationException),不应掩盖代码错误。
面试高频考点
Q1:faultTolerant() 开启了哪些能力?
开启后 Step 进入容错模式,解锁
skip()、retry()、noRollback()、skipPolicy()、retryPolicy()方法。容错模式下,框架会对跳过的记录单独开启一个事务重放整个 Chunk 以定位具体失败项。
Q2:skip 和 retry 的执行顺序?
先重试,后跳过。当异常匹配到
retry()时,框架重试最多retryLimit次。如果重试耗尽仍失败,且异常匹配skip(),则跳过该条记录。如果异常不匹配任何容错策略 → Step 失败。
上一章:Step 详解下一章:ExecutionContext 详解