Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Spring Batch job scope: avoid a shared bean in partition workers

Last updated: 7 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

A job-scoped bean is created for one job execution, but worker threads in a partitioned or multithreaded step do not automatically carry its scope context.

Choose the correct owner

A settlement run has one immutable exchange-rate snapshot. Job scope can expose a value to ordinary sequential steps because those steps execute within the job context. A partition worker has its own StepExecution and may run on a different thread or process. Do not inject a job-scoped object directly into code that expects every partition thread to resolve it. Pass an immutable snapshot ID through partition context and load it within the worker instead. Step scope fits values owned by each execution.

Make the value durable

A job-scoped field in memory is not a restart record. Save the snapshot identity in identifying parameters or a durable manifest, then check that it still names the same data after a crash. If the value is too large for job parameters, store it externally and pass a key. The input manifest establishes this ownership for file and query sources.

Prove parallel isolation

Run two jobs concurrently and divide each into partitions. Assert that every output row names the snapshot for its own job, never a neighboring launch. Kill a worker after one partition commits and restart that job. The restarted partition should reload the recorded snapshot ID rather than whichever snapshot is currently configured in the application.

Implementation contract

Java
record SettlementRun(String manifestId, String exchangeSnapshotId) {}

// Persist both identifiers before launch; partition workers receive IDs,
// not a mutable job-scoped service instance.
ExecutionContext workerInput = new ExecutionContext();
workerInput.putString("settlement.manifestId", run.manifestId());
workerInput.putString("settlement.exchangeSnapshotId", run.exchangeSnapshotId());

Cost and verification

Passing small identifiers costs little. Each worker may need one snapshot lookup, which should be cached by immutable ID with a bounded lifetime and included in capacity estimates.

Common Mistakes

  • Do not assume job scope is propagated to arbitrary partition threads.
  • Do not keep a restart-critical snapshot only in a JVM field.
  • Do not use one mutable singleton to switch snapshots between active jobs.

Read next

Spring Batch step scope: bind a reader to one execution, Spring Batch partitioner: assign disjoint receipt ranges, Spring Batch restart input: pin the manifest before resuming a cursor, Spring Batch job identity: a manifest ID defines restart versus a new run, Spring Batch parallel flows: make dependency order explicit.

spring
spring-batch
batch-job-scope-parallel-limit
Storage details