乐途乐途
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
主页
  • 计算机基础

    • TCP/IP
    • Linux
    • HTTP
  • 数据库

    • SQL
    • MySQL 5.7
  • 编程语言

    • C
    • C++
    • Java SE
    • Python2
    • Python3
  • 数据格式

    • JSON
    • XML
  • 认证与安全

    • JWT
  • 工具

    • Markdown
  • Git

    • GitFlow
  • Quartz

    • Quartz
  • Java

    • Maven 入门
    • Maven 进阶
    • MyBatis
    • Spring
    • Spring MVC
  • Java

    • Spring Boot
    • Spring Cloud
    • Spring Cloud Alibaba
    • Spring Security
    • Spring AI
    • Spring Batch
    • Kafka
    • Java 设计模式
  • 缓存

    • Redis
  • 搜索引擎

    • Elasticsearch
  • 分布式协调

    • ZooKeeper
联系
阿里云
  • 学习路径
  • 第1章 批处理概述与 Spring Batch 核心理念

    • Spring Batch 概述
    • Job-Instance-Execution 三层生命周期
    • 三层架构
    • Chunk 处理模型
    • Tasklet 处理模型
  • 第2章 Job与作业配置

    • Job 详解
    • Job 配置
    • JobLauncher 详解
    • JobParameters 详解
    • JobRepository 详解
  • 第3章 Step与执行模型

    • Step 详解
    • Step 配置
    • ExecutionContext 详解
    • ItemStream 与状态管理
    • StepScope 与 JobScope
  • 第4章 ItemReader数据读取

    • ItemReader 详解
    • FlatFileItemReader 详解
    • JdbcItemReader 详解
    • MultiResourceItemReader 详解
  • 第5章 ItemProcessor 数据处理

    • ItemProcessor 详解
  • 第6章 ItemWriter 数据写出

    • ItemWriter 详解
    • FlatFileItemWriter 详解
    • CompositeItemWriter 详解
    • JdbcBatchItemWriter 详解
  • 第7章 Chunk 处理与事务边界

    • Chunk 处理模型详解
    • 事务边界
  • 第8章 作业参数与启动

    • 命令行与 Web 启动
  • 第9章 监听器与拦截器

    • 监听器详解
  • 第10章 重启重试与跳过策略

    • 重启与重试
    • 跳过策略
  • 第11章 作业流与条件决策

    • 作业流与条件决策
  • 第12章 分区与并行处理

    • 分区详解
    • 并行 Step 与 Split
  • 第13章 与 Spring Boot 集成实践

    • Spring Boot 集成
  • 第15章 运维与监控

    • 大作业设计模式
    • 运维与监控

Chunk 处理模型详解

本章定位:彻底理解 Spring Batch 的核心执行模型——Chunk 循环,掌握事务边界、提交频率优化和 ChunkListener。

定义与作用

Chunk(块) 是 Spring Batch 中 Step 执行的基本事务单元。一个 Chunk Step 的循环是:读 N 条 → 逐条处理 → 一次性写 N 条 → 提交事务。这个过程反复执行直到数据读完。

飞翔科技架构师白歌的解释:

"Chunk 就像搬家的纸箱。搬家工人(Reader)一件一件(read)把家具从旧房子搬出来,放进箱子。箱子满了(Chunk Size 达标),一辆卡车(Writer)一次性把整箱家具(write)运到新房子。运到后签字确认(COMMIT)。"

核心原理

Chunk 循环的完整流程

事务边界

┌─────────────────── Chunk 事务 ───────────────────┐
│  ItemReader.read() × 10                           │
│  ItemProcessor.process() × 10                     │
│  ItemWriter.write(chunk)                          │
│  ──────────────────────────────────────────────── │
│  COMMIT                                            │
└──────────────────────────────────────────────────┘

关键规则:

规则说明
一个 Chunk = 一个事务Reader/Processor/Writer 共享同一事务
commit-interval = chunk-size框架每 chunk-size 条提交一次
最后不足 chunk-size 的剩余数据也会作为一个 Chunk 提交
Writer 失败整个 Chunk 回滚,Reader 指针回到 Chunk 起始位置
Chunk 提交后ExecutionContext 立即持久化

完整示例

场景一:飞翔科技——Chunk Size 调优

@Bean
public Step tunedImportStep(JobRepository jobRepository,
                              PlatformTransactionManager tx,
                              ItemReader<Order> reader,
                              ItemProcessor<Order, OrderEntity> processor,
                              ItemWriter<OrderEntity> writer) {
    return new StepBuilder("tunedImportStep", jobRepository)
            .<Order, OrderEntity>chunk(500, tx)  // Chunk Size=500
            .reader(reader)
            .processor(processor)
            .writer(writer)
            .build();
}

Chunk Size 影响分析:

Chunk Size事务数(10 万条)事务开销回滚粒度内存占用
1010000极高细(10 条)低
1001000中中(100 条)低
500200低粗(500 条)中
1000100极低很粗(1000 条)较高

场景二:ChunkListener 监控

@Component
public class ChunkMonitorListener implements ChunkListener {

    private long chunkStartTime;

    @Override
    public void beforeChunk(ChunkContext context) {
        chunkStartTime = System.currentTimeMillis();
        System.out.println("Chunk #" + context.getStepContext()
            .getStepExecution().getCommitCount() + " 开始");
    }

    @Override
    public void afterChunk(ChunkContext context) {
        long duration = System.currentTimeMillis() - chunkStartTime;
        int readCount = context.getStepContext().getStepExecution().getReadCount();
        System.out.println("Chunk 完成,耗时: " + duration + "ms, "
            + "累计读取: " + readCount);
    }

    @Override
    public void afterChunkError(ChunkContext context) {
        System.out.println("Chunk 失败!回滚到上一个检查点");
    }
}

运行结果:

Chunk #1 开始
Chunk 完成,耗时: 230ms, 累计读取: 500
Chunk #2 开始
Chunk 完成,耗时: 215ms, 累计读取: 1000
Chunk #3 开始
Chunk 失败!回滚到上一个检查点
  → Reader 指针回到第 1001 条,重新读 500 条
Chunk #3 开始(重试)
Chunk 完成,耗时: 260ms, 累计读取: 1500

易错场景与避坑

反例一:Chunk Size 过大导致 OOM

// ❌ Chunk Size=50000 → 内存中缓冲 5 万条对象 → OOM
.chunk(50000, tx)

正确做法:Chunk Size 通常设置在 10-1000 之间。大数据对象(含 BLOB)应使用更小的 Chunk Size。

反例二:Processor 中的操作影响事务时间

// ❌ Processor 中每条数据调一次外部 API(耗时 2s)
// Chunk Size=100 → 一个事务持续 200s → 数据库锁长期持有
@Override
public OrderEntity process(Order order) {
    String result = slowExternalApi.call(order.getId()); // 2s
    return transform(order, result);
}

面试高频考点

Q1:Chunk 的事务边界是什么?

一个 Chunk 的所有 Reader/Processor/Writer 操作在同一个事务中。Writer 成功 → COMMIT。Writer 失败 → 整个 Chunk ROLLBACK。Reader 指针在 COMMIT 时才推进。

Q2:Chunk Size 太小或太大的后果?

太小:事务数多,COMMIT 开销大,性能差。太大:内存占用高,事务时间长,数据库锁竞争激烈,回滚粒度粗。建议 50-500 之间根据单条数据大小调整。


上一章:CompositeItemWriter 详解下一章:作业参数与启动

下一页
事务边界