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

    • 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章 运维与监控

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

Step 详解

本章定位:深入理解 Step 的执行模型——它是 Job 的执行单元,是 Chunk 循环和 Tasklet 逻辑的实际载体。

定义与作用

Step 是 Job 中的独立执行单元,代表批处理过程中的一个逻辑阶段。每个 Step 封装了具体的数据处理逻辑(Chunk 流水线或 Tasklet 操作),拥有独立的事务边界、执行状态和重启策略。

飞翔科技架构师白歌在团队技术分享中解释:

"Job 是剧本,Step 是每一场戏。只有所有场次演完,整部剧(Job)才算完成。如果第三场戏演砸了,导演(Spring Batch)可以从第三场重新开始,不用从头演。"

Step 的职责:

Step 负责Step 不负责
封装 Reader → Processor → Writer 循环(Chunk)或单一操作(Tasklet)跨 Step 的数据传递(那是 ExecutionContext 的职责)
管理自己的事务边界Job 级别的编排流程(那是 Job 的职责)
记录自己的执行状态(read/write/skip count)数据库连接管理
应用容错策略(Skip/Retry)调度和定时触发

核心原理

Step 生命周期

Step 类型决策流程

完整示例

场景一:飞翔科技——Chunk Step 处理学生成绩

背景:小崔需要实现一个 Step,从 CSV 读取学生成绩,计算 GPA,写入数据库。

@Configuration
@EnableBatchProcessing
public class GradeStepConfig {

    @Bean
    public Step gradeProcessingStep(JobRepository jobRepository,
                                      PlatformTransactionManager tx,
                                      FlatFileItemReader<GradeDTO> reader,
                                      ItemProcessor<GradeDTO, GradeEntity> processor,
                                      JdbcBatchItemWriter<GradeEntity> writer) {
        return new StepBuilder("gradeProcessingStep", jobRepository)
                .<GradeDTO, GradeEntity>chunk(50, tx)
                .reader(reader)
                .processor(processor)
                .writer(writer)
                .faultTolerant()
                .skip(FlatFileParseException.class)
                .skipLimit(10)
                .listener(new StepExecutionListener() {
                    @Override
                    public void beforeStep(StepExecution stepExecution) {
                        System.out.println("成绩处理开始");
                    }

                    @Override
                    public ExitStatus afterStep(StepExecution stepExecution) {
                        System.out.println("成绩处理完成: read=" + stepExecution.getReadCount()
                            + ", write=" + stepExecution.getWriteCount()
                            + ", skip=" + stepExecution.getSkipCount());
                        return stepExecution.getExitStatus();
                    }
                })
                .build();
    }
}

运行结果:

成绩处理开始
Chunk 1: read 50, processed 50, wrote 50 → COMMIT (skip=0)
Chunk 2: read 50, processed 50, wrote 50 → COMMIT (skip=0)
Chunk 3: read 50, processed 49, wrote 49 → COMMIT (skip=1, line 123 parse error)
...
Chunk 100: read 50, processed 50, wrote 50 → COMMIT (skip=0)
成绩处理完成: read=5000, write=4980, skip=10

场景二:Tasklet Step 执行存储过程

@Bean
public Step settlementStep(JobRepository jobRepository,
                            PlatformTransactionManager tx) {
    return new StepBuilder("settlementStep", jobRepository)
            .tasklet((contribution, chunkContext) -> {
                String month = chunkContext.getStepContext()
                        .getJobParameters().get("settlementMonth").toString();
                System.out.println("开始结算: " + month);
                // 调用存储过程
                contribution.incrementWriteCount(1);
                return RepeatStatus.FINISHED;
            }, tx)
            .build();
}

操作前后对比:

易错场景与避坑

反例一:Chunk Step 忘记配置 ItemReader

// ❌ 编译通过但运行时崩溃
return new StepBuilder("step", jobRepository)
        .<String, String>chunk(10, tx)
        // 忘记 .reader()
        .writer(writer)
        .build();
// NullPointerException: reader is required

反例二:Step 中修改全局状态

// ❌ Step 不应修改类级别共享状态
@Component
public class BadProcessor implements ItemProcessor<Student, Student> {
    private int processedCount = 0; // ❌ 非线程安全、无法持久化

    @Override
    public Student process(Student item) {
        processedCount++; // ❌ 重启后从 0 开始
        return item;
    }
}

正确做法:计数通过 StepExecution 的 ReadCount/WriteCount 管理,状态通过 ExecutionContext 持久化。

面试高频考点

Q1:Step 的 Chunk 模式和 Tasklet 模式如何选型?

Chunk 模式:数据流处理(ETL),框架自动管理事务边界和断点续传。Tasklet 模式:单一操作(清理/通知/存储过程),不需要 Reader/Processor/Writer 流水线。大数据量处理必须用 Chunk。

Q2:Step 的 ExitStatus 和 BatchStatus 有什么区别?

BatchStatus 是 Step 的完成状态(COMPLETED/STARTED/FAILED),由框架管理。ExitStatus 是 Step 的退出状态码(可自定义),用于 Job 中的条件路由(on("HIGH_SALES").to(...))。


上一章:JobRepository 详解下一章:Step 配置

下一页
Step 配置