A durable repository cannot reconstruct the same import if the source rows change between executions.
Spring Batch restart input: pin the manifest before resuming a cursor
Freeze the source set
The checked two-process fixture keeps four database rows unchanged. A real import may read a CSV replaced at the same path or a query whose result changes while the job is down. Persist a manifest that names an immutable object version or source snapshot, includes a count and digest, and becomes part of the job's business identity. A location string by itself is not a version.
Reject changed replay
Before resuming, recompute the manifest digest or reopen the immutable object version. If it differs, fail for review. Do not let an upsert writer conceal a changed receipt under the same source ID. For mutable database sources, use a snapshot or a bounded query over versioned rows; a new row inserted ahead of the cursor can shift ordering if the reader relies on position.
Separate correction from restart
A corrected source file is a new business input. Give it a new manifest identity and record its relationship to the earlier failed one. Reusing the old identity with new bytes makes the saved checkpoint meaningless. The checked kit now mutates ID 4 after failure and rejects the same-manifest restart before a new Batch execution is created. The digest test remains a gate against change at launch, not an immutable database snapshot.
Boundary sketch
record ImportManifest(String manifestId, String sourceVersion,
long sourceCount, String sha256) {}
// Reopen the pinned sourceVersion and compare its digest before restart.Cost and verification
Immutable input consumes storage and retention time. Digesting a large source is linear in its byte size and may require a separate pass.
Common Mistakes
- Do not treat a pathname as immutable input.
- Do not resume a positional cursor over a reordered query result.
- Do not overwrite a changed receipt because its ID already exists.
Read next
Spring Batch restart across two JVMs after a recorded failed execution, Spring Batch writers: use a stable source key when a chunk is replayed, Spring Batch job identity: a manifest ID defines restart versus a new run, Spring Batch reconciliation: report accepted and rejected receipt IDs.
