Spring Batch 6.0.4 与 5.2.6 同日发布:该选哪个,怎么升级

2026-06-10 14 预计阅读时间: 1 分钟
来源: spring.io AI 摘要 Original link

Disclaimer: This article is an AI-assisted summary. Read it together with the original source when precision matters. The summary may omit context, version differences, or edge cases and is not official documentation.

预计阅读时间:9 分钟

Spring Batch 近期同时推出了 6.0.45.2.6 两个维护版本。两个版本在同一天发布,说明团队仍在并行维护两条主线——6.x 面向 Spring Framework 6 / Java 17+ 的新项目,5.x 继续为尚未完成 Java 版本升级的存量系统提供安全与稳定性保障。

如果你正在评估 Spring Batch 或准备迁移版本,这次双线发布是一个很好的切入点:搞清楚两条线的差异,才能做出正确的依赖选择。

两条维护线的定位差异

Spring Batch 6.x 系列随 Spring Boot 3.x 一起演进,底层依赖 Spring Framework 6,最低要求 Java 17。它引入了若干结构性变更——比如对 ItemStream 生命周期管理的调整、对 JobRepository 接口的精简、以及与 Spring Framework 6 的观测体系(Observation API)的集成。

5.x 系列则停留在 Spring Framework 5 的生态里,最低支持 Java 8(5.2.x 实际建议 Java 11+),适合仍在运行 Spring Boot 2.x 的项目。5.2.6 这类补丁版本主要修复已知缺陷和兼容性问题,不会引入新特性。

简单判断规则:

条件 推荐版本
新项目,Spring Boot 3.x,Java 17+ 6.0.4
存量项目,Spring Boot 2.x,Java 8/11 5.2.6
正在从 5.x 迁移到 6.x 先升到 5.2.6 确保稳定,再跨版本迁移

6.0.4 补丁关注什么

作为 6.0 线的第四次补丁,6.0.4 主要修复的是 6.0.0 引入新架构后暴露的边界问题。常见的补丁方向包括:

  • JobRepository 事务边界修正:6.0 重构了 JobRepository 的实现,早期版本在某些并发场景下可能出现死锁或事务超时,补丁版本逐步收紧了锁的范围。
  • StepExecution 序列化兼容:6.0 调整了 StepExecution 的字段结构,补丁修复了与旧版本数据库记录的兼容读取问题。
  • Observation API 集成完善:6.0 开始用 Micrometer Observation 替代旧版 BatchMetrics,补丁版本补充了缺失的指标标签和上下文传递。

如果你的项目已经在用 6.0.0–6.0.3,升级到 6.0.4 是低风险的——补丁版本不改变公共 API 签名。

5.2.6 补丁关注什么

5.2.6 是 5.x 线的第六次补丁,修复范围更偏向存量系统的实际痛点:

  • 数据库方言兼容:某些数据库(如 DB2、MariaDB 特定版本)的 JobRepository SQL 脚本存在语法问题,补丁做了针对性修正。
  • Chunk-oriented 处理边界条件:在 faultTolerant 步骤中,skipretry 的叠加逻辑在特定异常组合下可能跳过不该跳过的记录,补丁收紧了判定逻辑。
  • FlatFileItemReader/Writer 编码处理:部分非 UTF-8 编码的文件在读取时出现截断,补丁修正了 BufferedReader 的编码初始化顺序。

实践:用 Spring Batch 6.0.4 写一个最小可运行 Job

下面给出一个完整的、可直接复制运行的最小 Spring Batch 项目示例。假设你使用 Spring Boot 3.2+ 和 Java 17。

项目依赖(pom.xml 关键片段)

<properties>
    <java.version>17</java.version>
    <spring-batch.version>6.0.4</spring-batch.version>
</properties>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-batch</artifactId>
    </dependency>
    <!-- 内存 JobRepository,不需要真实数据库;生产环境请换为 JDBC -->
    <dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <scope>runtime</scope>
    </dependency>
</dependencies>

生产环境务必把 HSQLDB 换成 MySQL / PostgreSQL 等持久化数据库,并配置 spring.batch.jdbc.initialize-schema=always 或使用 Flyway 管理 schema。

Job 配置类

package com.example.batch;

import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.Chunk;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;

@Configuration
public class HelloBatchConfig {

    // --- Reader:逐条返回数据,返回 null 表示结束 ---
    @Bean
    ItemReader<String> reader() {
        String[] data = {"alice", "bob", "carol", "dave"};
        // 用数组索引模拟有界读取
        return new ItemReader<>() {
            private int idx = 0;
            @Override
            public String read() {
                return idx < data.length ? data[idx++] : null;
            }
        };
    }

    // --- Processor:把名字转成大写 ---
    @Bean
    ItemProcessor<String, String> processor() {
        return name -> name.toUpperCase();
    }

    // --- Writer:打印到控制台 ---
    @Bean
    ItemWriter<String> writer() {
        return chunk -> chunk.forEach(System.out::println);
    }

    // --- Step:chunk 大小 2,每次处理两条记录 ---
    @Bean
    Step helloStep(JobRepository jobRepository,
                   PlatformTransactionManager txManager,
                   ItemReader<String> reader,
                   ItemProcessor<String, String> processor,
                   ItemWriter<String> writer) {
        return new StepBuilder("helloStep", jobRepository)
                .<String, String>chunk(2, txManager)
                .reader(reader)
                .processor(processor)
                .writer(writer)
                .build();
    }

    // --- Job ---
    @Bean
    Job helloJob(JobRepository jobRepository, Step helloStep) {
        return new JobBuilder("helloJob", jobRepository)
                .start(helloStep)
                .build();
    }
}

启动类

package com.example.batch;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class HelloBatchApp {
    public static void main(String[] args) {
        SpringApplication.run(HelloBatchApp.class, args);
    }
}

运行与预期输出

# 打包并运行
mvn clean package -DskipTests
java -jar target/hello-batch-app-0.0.1-SNAPSHOT.jar

控制台应输出:

ALICE
BOB
CAROL
DAVE

每两条记录作为一个 chunk 提交一次事务——你可以把 chunk 大小改成 1 或 4 来观察提交频率的变化。

从 5.x 迁移到 6.x 的实操要点

如果你决定从 5.2.6 升到 6.0.4,以下是最容易踩坑的几处:

  1. Java 版本先到位:6.x 要求 Java 17,这是硬性前提,没有妥协空间。
  2. JobRepository API 变化:6.0 把部分方法签名从 JobRepository 接口移除或重命名,自定义实现需要对照迁移指南逐条检查。
  3. Schema 变更:6.0 的 BATCH_JOB_INSTANCE 等表结构与 5.x 有字段差异。迁移时要么清空旧表重新初始化,要么执行官方提供的增量 DDL 脚本。
  4. Metrics 替换:如果你在 5.x 中使用了 BatchMetrics,6.x 改为 Micrometer Observation API,需要重新注册指标并调整标签体系。
  5. 先升到 5.2.6 再跨版本:确保 5.x 线上所有已知 bug 已修复,再开始 6.x 迁移,可以减少排查时的干扰变量。

升级检查清单

在决定版本和执行升级前,逐项确认:

  • [ ] 当前项目的 Java 最低版本是否满足目标线的要求?
  • [ ] Spring Boot 版本是否与 Spring Batch 大版本对齐(Boot 3 → Batch 6,Boot 2 → Batch 5)?
  • [ ] JobRepository 的数据库 schema 是否需要增量迁移脚本?
  • [ ] 自定义的 ItemStream / JobRepository 实现是否需要适配新接口?
  • [ ] 监控指标是否从旧体系迁移到 Micrometer Observation?
  • [ ] 是否有第三方 Spring Batch 扩展(如 Spring Batch Integration)需要同步升级?

两条线并行维护是好事——它给了存量项目喘息空间,也给新项目提供了更现代的基础设施。选对版本线、按清单逐步迁移,比盲目追新更稳妥。


相关推荐