What is a StepExecution in Spring Batch, and which metrics/counts does it record?
answer
- one attempt at a Step, persisted
- read/write/filter/commit/rollback/skip
- read = write + filter (no skips)
- afterStep listener reads them
- BATCH_STEP_EXECUTION table
basics
~10 sA StepExecution represents one attempt to run a Step. It records runtime metrics: readCount, writeCount, filterCount, commitCount, rollbackCount, and skipCount, plus status, timestamps, and its own ExecutionContext.
solid answer
~30 sA StepExecution is the domain object Spring Batch creates for each attempt to execute a Step within a JobExecution. It is persisted to the metadata tables (BATCH_STEP_EXECUTION) and carries the step's runtime statistics: readCount (items read by the ItemReader), writeCount (items written by the ItemWriter), filterCount (items dropped by an ItemProcessor returning null), commitCount (chunk transactions committed), rollbackCount (chunk transactions rolled back), and skipCount (items skipped across read/process/write). It also holds BatchStatus, ExitStatus, start/end times, and a per-step ExecutionContext used for restart. These counts let you audit throughput and drive restart/monitoring logic, typically read in a StepExecutionListener's afterStep.
code
java · 14 linespublic class MetricsListener implements StepExecutionListener {
@Override
public ExitStatus afterStep(StepExecution se) {
long read = se.getReadCount();
long written = se.getWriteCount();
long filtered = se.getFilterCount();
long skipped = se.getSkipCount(); // read+process+write skips
long commits = se.getCommitCount();
long rollbacks= se.getRollbackCount();
log.info("read={} written={} filtered={} skipped={} commits={} rollbacks={}",
read, written, filtered, skipped, commits, rollbacks);
return se.getExitStatus(); // return null to keep the default
}
}go deeper
Name the object and list the main counts; know they're read in afterStep.
Explain read=write+filter, that commitCount is per chunk, and where counts are persisted.
Connect counts to chunk transaction boundaries and restart semantics (new StepExecution, ExecutionContext for resume).
Discuss using these metrics for SLA/throughput monitoring and audit, plus how skip/retry perturbs commit/rollback counts.
### What a StepExecution is Spring Batch persists job metadata. A `JobExecution` is one run of a `Job`; within it, each `Step` that runs produces a `StepExecution` — the record of a **single attempt** to execute that step. If a step is restarted after failure, a **new** StepExecution is created for the new attempt (the old one is retained). StepExecutions are stored in the `BATCH_STEP_EXECUTION` table by the `JobRepository`. ### The counts it tracks For a **chunk-oriented step** (read → process → write in chunks), the StepExecution accumulates: - **readCount** — number of items successfully returned by the `ItemReader`. - **writeCount** — number of items successfully handed to the `ItemWriter`. - **filterCount** — items that were read but **filtered out** by the `ItemProcessor` returning `null` (not an error, not written). Roughly: `readCount = writeCount + filterCount` when there are no skips. - **commitCount** — number of chunk **transactions committed** (one per successful chunk, so roughly `ceil(items / chunkSize)`). - **rollbackCount** — number of chunk transactions **rolled back**, e.g. on a write exception or during skip/retry re-processing. - **skipCount** — total skipped items = `readSkipCount + processSkipCount + writeSkipCount` (skip policy caught an exception and the item was skipped instead of failing the step). ### Other fields Beyond counts it holds `BatchStatus` (STARTED/COMPLETED/FAILED…), `ExitStatus`, `startTime`/`endTime`, a `failureExceptions` list, and a step-scoped `ExecutionContext` (persistent state used to resume a restart, e.g. a reader's last-read position). ### How you read them Counts are typically inspected in a `StepExecutionListener.afterStep(StepExecution)` (or via `@AfterStep`), or queried later from `JobExplorer`/the metadata tables for monitoring dashboards. ### Gotchas - readCount/writeCount are **not** the same when a processor filters items — that gap is `filterCount`, not a skip. - commitCount is per-chunk-transaction, not per-item. - A tasklet-style step (not chunk-oriented) generally leaves read/write/filter counts at 0 — those metrics are meaningful for chunk steps. - These are cumulative totals for that one attempt; on restart the fresh StepExecution starts them back at 0.
- Where are these counts persisted, and how would you query them after the job finishes?In the BATCH_STEP_EXECUTION metadata table written by the JobRepository. After the fact you read them via JobExplorer.getJobExecution(...).getStepExecutions() (or the JobOperator), or by querying the table directly for a monitoring dashboard.
- If a step is restarted, do the counts continue from where they left off?No. A restart creates a brand-new StepExecution with counts starting at 0. Continuity of work (e.g. where the reader resumes) comes from the persisted ExecutionContext, not from the counters.
saying these in an interview costs you the question
- Saying readCount always equals writeCount (ignores filterCount and skips)
- Claiming commitCount is the number of items (it's the number of chunk transactions)
- Thinking a StepExecution is reused across restarts instead of created fresh