spring boot集成spring batch处理大批量数据的关键在于读取、处理、写入三环节的资源适配与流程控制:分页读取防oom,合理设置chunk大小平衡性能与稳定性,启用批量写入机制,按需采用并行或分片提升吞吐。

Spring Boot 集成 Spring Batch 处理大批量数据,关键不在“能不能跑起来”,而在于“怎么不崩、不慢、不丢、不重”。核心是围绕读取、处理、写入三个环节做资源适配与流程控制,而不是堆配置。
用对读取方式,避免内存溢出
别用 JdbcCursorItemReader 直接查几百万条——它底层靠 JDBC ResultSet 流式拉取,但若 SQL 没加 ORDER BY 或数据库没开游标支持,可能一次性加载到内存。更稳妥的是分页驱动:
- 搭配
MyBatis-PageHelper:在ItemReader中调用带PageHelper.startPage()的 DAO 方法,利用其ThreadLocal隔离性保障多线程安全; - 或改用
JdbcPagingItemReader:显式配置PageQueryProvider和排序字段,由框架控制分页参数(如id > ?),避免OFFSET/LIMIT深分页性能退化; - fetchSize 设为 50–100:过大会占内存,过小会增加网络往返次数,MySQL 默认 0 表示全拉,必须显式设置。
调好 Chunk 大小和事务边界
Chunk 是 Spring Batch 的最小执行单元,也是事务边界。设得太小(如默认 10),频繁提交拖慢数据库;设太大(如 10000),失败时回滚代价高、OOM 风险上升。
你接手一个需求时,是不是经常这样:"改一个小字段 → 结果把不相关的代码也改了"、"需求说得很模糊 → 做着做着发现跑偏了"、"数据库加个字段 → 上线才发现漏了数据兼容"、"做了个新功能 → 一个月后自己都忘了当时怎么设计的"、"写到一半被中断 → 再回来不知道从哪继续";这个 Skill 就是专门解决这些问题的。 它会自动探测你的项目环境(JDK、Spring Boot、ORM、数据库、前端框架),记在
- 推荐起始值:数据库写入类任务设为 500–1000,CPU 密集型处理类任务可设为 100–200;
- 配合
@Transactional使用:确保ItemWriter写入逻辑在同一个事务内完成,避免跨事务数据不一致; - 慎用
commit-interval全局配置:它只作用于简单 chunk 场景,复杂流程建议在 Step 级用.chunk(500)显式声明。
批量写入必须启用批处理能力
单条 INSERT 是批处理性能杀手。无论用 JPA 还是 JDBC,都要激活批量机制:
-
JdbcBatchItemWriter:设置setSql("INSERT INTO ...")+setItemSqlParameterSourceProvider(...),底层调用PreparedStatement.addBatch(); - JPA 场景:开启
spring.jpa.properties.hibernate.jdbc.batch_size=50,并确保实体 ID 生成策略支持批量(如@GeneratedValue(strategy = GenerationType.SEQUENCE)); - 避免在
ItemProcessor中触发额外 DB 查询:把关联数据提前查好、缓存或用 Map 预加载,防止 N+1 问题拖垮吞吐。
按需启用并行与分片能力
单机吞吐见顶后,不要硬扛,要拆:
- Step 内并行:用
AsyncTaskExecutor包装ItemProcessor,适合 CPU 密集型转换(如加解密、格式转换); - Step 级并行:通过
Split定义多个子 Step,各自读不同数据段(如按时间范围或 ID 区间),共享同一 JobRepository; - 分布式分片:结合
JobExplorer+ 自定义PartitionHandler(如调用 REST 或消息队列分发),Worker 节点从 Redis 或 DB 获取分片参数,实现千万级数据小时级完成。










