skip to content

Explain how JobParameters drive the difference between restarting a failed job and starting a new instance.

level: seniorimportance: should knowfreq 45%

answer

  1. identity switch, not an API flag
  2. same identifying params + FAILED/STOPPED => resume
  3. same params + COMPLETED => already-complete exception
  4. new/incremented identifying params => fresh instance from start
  5. never put timestamp in identifying params

basics

~10 s

Same identifying parameters as a failed run means restart: Spring Batch finds the incomplete JobInstance and resumes it. Different identifying parameters (or an incremented run.id) means a brand-new JobInstance that starts from scratch.

solid answer

~40 s

JobInstance identity — job name plus identifying JobParameters — is the switch. If you launch with identifying parameters matching an existing JobInstance that is FAILED or STOPPED (not COMPLETED), Spring Batch treats it as a restart: it locates that incomplete instance, creates a new JobExecution, and resumes from the last checkpointed step/chunk. If the parameters match a COMPLETED instance, it refuses with JobInstanceAlreadyCompleteException. If the identifying parameters are new — or you used a JobParametersIncrementer to bump run.id — it creates a fresh JobInstance that starts from the beginning. So restart is not a separate API flag: it's implied by re-supplying identical identifying parameters for an unfinished instance. Practical consequences: don't put volatile values like System.currentTimeMillis() in identifying parameters, or you'd make restart impossible; keep the business key identifying and volatile bookkeeping non-identifying.

code

java · 13 lines
java
// GOOD: businessDate identifying, timestamp non-identifying -> restartable.
JobParameters p = new JobParametersBuilder()
    .addLocalDate("businessDate", LocalDate.of(2026, 7, 1))       // identifying
    .addLong("launchedAt", System.currentTimeMillis(), false)     // non-identifying
    .toJobParameters();

// If a prior run for businessDate=2026-07-01 FAILED, relaunching with the same
// identifying businessDate resumes it from the last checkpoint (a restart).
// If launchedAt were identifying, each launch would be a new instance and the
// failed run could never be resumed.

// Restart by execution id (reuses that instance's identifying params):
jobOperator.restart(previousFailedExecutionId);

go deeper

for a junior

Grasp that same params can mean resume, new params mean fresh run.

for a middle

State the three-way decision: no instance / completed / failed.

for a senior

Explain checkpoint resumption from ExecutionContext and identifying-parameter hygiene.

for a principal

Architect parameter schemes and operational tooling (JobOperator.restart, JobExplorer) for reliable restartable pipelines.

## The mental model Spring Batch has no explicit "restart vs new" toggle at launch. What happens is **derived** from `JobParameters` and the state of the matching `JobInstance`. Recall: **`JobInstance` identity = job name + identifying `JobParameters`**. A `JobInstance` has a `BatchStatus` reflecting its most recent `JobExecution`. ## Decision table when you call JobLauncher.run(job, params) Spring Batch looks up the `JobInstance` for those identifying params: 1. **No matching instance** → create a **new `JobInstance`**, run from the start. 2. **Matching instance, last status COMPLETED** → throw `JobInstanceAlreadyCompleteException` (duplicate-run guard). 3. **Matching instance, last status FAILED or STOPPED** → **restart**: create a new `JobExecution` under the *same* `JobInstance` and **resume** from the last successful step / last committed chunk (subject to the step's checkpoint/`ExecutionContext`). There are refinements — a step marked `allowStartIfComplete(true)` re-runs even if it completed; a job's `preventRestart()` disables restart; and a step's start-limit caps restart attempts — but the parameter-driven identity is the core switch. ## Why identifying-parameter hygiene matters Because restart *requires re-supplying the same identifying parameters*, any value that is unique per wall-clock launch (a timestamp, a UUID) must **not** be identifying — otherwise every launch is a new instance and a failed run can never be restarted, only re-run from scratch. Conversely, `RunIdIncrementer` deliberately changes an identifying `run.id` precisely to force **new** instances for repeatable jobs — the opposite intent. Recommended scheme: - **Identifying:** the logical business key (`businessDate`, `batchId`, `region`). - **Non-identifying:** launch timestamp, trigger source, debug flags. ## Restart resumption details On restart the framework reads the persisted `ExecutionContext` for the job and steps from the metadata tables (`BATCH_JOB_EXECUTION_CONTEXT`, `BATCH_STEP_EXECUTION_CONTEXT`). Chunk-oriented steps resume near the last commit point; item counts and reader state (if the reader saved its position) are restored. Restart is only meaningful because the previous execution persisted this state. ## Common interview traps - "Restart" and "start next instance" are different: restart resumes an *unfinished* instance (same params); `startNextInstance` + incrementer creates the *next* instance (changed identifying params). - You cannot restart a **COMPLETED** instance by re-running it — you'd get the already-complete exception; you'd need a different identifying parameter set. - Putting a timestamp in identifying parameters is the classic bug that silently defeats restart. ## Operational APIs `JobOperator.restart(executionId)` restarts by execution id and internally reuses that instance's identifying parameters. `JobExplorer`/`JobRepository` let you inspect instance/execution state to decide.

  • What common mistake with JobParameters makes a failed job impossible to restart?
    Putting a per-launch unique value (System.currentTimeMillis(), a UUID) in an identifying parameter. Every launch then resolves to a new JobInstance, so Spring Batch never sees the prior failed instance to resume. Mark such values non-identifying instead.
  • Can you restart a JobInstance whose last status is COMPLETED?
    No. Re-running with the same identifying params throws JobInstanceAlreadyCompleteException. To process again you need a different identifying parameter set (or an incrementer), which creates a new instance that starts from the beginning.

saying these in an interview costs you the question

  • Believing there is an explicit restart flag on JobLauncher.run
  • Saying restart works with different identifying parameters
  • Putting a timestamp in identifying parameters and still expecting restart to work
  • Confusing restart (resume same instance) with startNextInstance (new instance)

context