Skip to content

Installation

Upgrading from 2.x?

3.0.0 is a platform release (Spring Boot 4 / Spring Batch 6 / Java 21). See the Migration Guide.

Requirements

  • Java 21+
  • Spring Boot 4.1+ / Spring Batch 6 (the 2.x line targets Spring Boot 3)
  • A relational database (PostgreSQL, MySQL, MariaDB, Oracle, SQL Server, Db2, or H2 for development)

1. Add the dependency

Maven:

<dependency>
    <groupId>io.github.jchejarla</groupId>
    <artifactId>spring-batch-db-cluster-core</artifactId>
    <version><!-- the version shown in the selector above --></version>
</dependency>

The core artifact pulls in Spring Boot's web, batch, jdbc, and actuator starters transitively, so you don't add those. It does not bring a database driver — add the one for your database yourself:

<!-- H2 for the zero-setup quick start (use runtime scope) -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>
<!-- ...or com.mysql:mysql-connector-j / org.postgresql:postgresql / etc. for a server DB -->

Testing a SNAPSHOT build?

SNAPSHOTs are pre-release, not official versions. To consume one, add the snapshot repository:

<repositories>
  <repository>
    <id>central-snapshots</id>
    <url>https://central.sonatype.com/repository/maven-snapshots/</url>
    <snapshots><enabled>true</enabled></snapshots>
    <releases><enabled>false</enabled></releases>
  </repository>
</repositories>

2. Use a JDBC JobRepository

Spring Batch 6 defaults to an in-memory ResourcelessJobRepository that persists nothing. A cluster coordinates through shared, persisted job metadata, so a JDBC-backed repository is required. Enable it on a configuration class:

@SpringBootApplication
@EnableBatchProcessing
@EnableJdbcJobRepository   // dataSourceRef defaults to "dataSource"
public class MyApplication { }

Both annotations are needed — @EnableJdbcJobRepository is inert without @EnableBatchProcessing. If clustering is enabled on the resourceless repository, startup fails fast with an actionable message.

3. Create the schema

Two layers of tables must exist: the Spring Batch core tables and this library's cluster tables (BATCH_NODES, BATCH_JOB_COORDINATION, BATCH_PARTITIONS, BATCH_JOB_PHASE_EVENTS). Spring Boot 4 no longer auto-creates the Batch tables, so create both explicitly. The simplest portable way is spring.sql.init, pointing at the DDL that ships for your database — pick the matching suffix (-h2, -postgresql, -mysql, -mariadb, -oracle, -sqlserver, -db2):

spring:
  sql:
    init:
      mode: always
      continue-on-error: true   # tolerate "already exists" across restarts and peer nodes
      schema-locations:
        - classpath:org/springframework/batch/core/schema-h2.sql   # 1. Spring Batch core tables
        - classpath:schema/schema-h2.sql                            # 2. this library's cluster tables

Order matters — the cluster tables have foreign keys to the Spring Batch tables, so the core schema must be listed first. (For production, prefer a migration tool — Flyway/Liquibase — with spring.batch.cluster.initialize-schema=never.)

Don't rely on initialize-schema=embedded for the H2 file demo

spring.batch.cluster.initialize-schema defaults to embedded, which auto-creates the cluster tables only for genuinely in-memory databases. It does not fire for file-mode H2 (the multi-node demo path) or any server database — for those you must create the cluster tables yourself (via spring.sql.init as above, or a migration tool), and set initialize-schema: never.

See Configuration for the full initialize-schema semantics.

4. Enable clustering

spring:
  batch:
    cluster:
      enabled: true
      node-id-prefix: ${HOSTNAME:batch-node}   # optional; a unique suffix is added automatically

5. A complete, runnable config (zero-setup H2, multi-node)

Putting it together — a full application.yml that forms a real cluster from multiple JVMs on one machine using file-mode H2 (no external database). Copy this, then start two instances on different ports (--server.port=8081, --server.port=8082); they share the H2 file and form a cluster.

Start the first node first

On the H2 file path, start one node and wait until it's up before starting the others — if several JVMs launch at the exact same instant they can race to create the shared ./build directory / H2 file. (A server database like Postgres/MySQL has no such race.)

spring:
  datasource:
    # AUTO_SERVER lets multiple JVMs share one H2 file — the first becomes an embedded server for the
    # rest. Swap this for a Postgres/MySQL/... datasource in production.
    url: jdbc:h2:file:./build/cluster-demo;AUTO_SERVER=TRUE;DB_CLOSE_DELAY=-1;MODE=PostgreSQL
    driver-class-name: org.h2.Driver
    username: sa
    password:
  sql:
    init:
      mode: always
      continue-on-error: true
      schema-locations:
        - classpath:org/springframework/batch/core/schema-h2.sql
        - classpath:schema/schema-h2.sql
  batch:
    job:
      enabled: false          # jobs are triggered on demand (REST/scheduler), NOT auto-run at startup
    cluster:
      enabled: true
      initialize-schema: never # the schema is created above via spring.sql.init

management:
  endpoints:
    web:
      exposure:
        include: health,info,batch-cluster,batch-cluster-jobs

spring.batch.job.enabled=false is important: without it, Spring Boot runs your job at startup — before the cluster forms — and it fails. Trigger jobs yourself once the app is up.

That's it — your existing job and step definitions are unchanged. Next, implement a ClusterAwarePartitioner and wire it with the ClusterAwarePartitionHandler — see the Usage guide.