Spring Batch Retry and Skip Logic for Fault-Tolerant Jobs
Fast recall
Quick revision
Core answer
SkipListener and RetryListener they let you build fault-tolerant pipelines that survive dirty data and infrastructure flaps without aborting the entire batch run.Understanding of where retry and skip apply (read, process, write phases) and their interaction with the chunk transaction
Applying skip to write-phase exceptions without considering that a failed write rolls back the entire chunk — Spring Batch then re-reads items one at a time to isolate the bad row, which surprises many candidates
Explain the chunk retry rollback cycle and how Spring Batch uses single-item recovery after a write failure to isolate the offending record, plus `noRollback` and `processorTransactional(false)` for non-transactional side effects
Interview-ready guide
Interview answer
Spring Batch's fault tolerance has two complementary policies — skip and retry — and a third concept around when rollback applies.
Skip — discard and continue:
- For predictable bad records (parse, validation)
faultTolerant().skip(Exception.class).skipLimit(N)- SkipListener fires for every skipped item — write to a dead-letter destination
Retry — try again:
- For transient failures (deadlock, 503)
faultTolerant().retry(Exception.class).retryLimit(N).backOffPolicy(...)- ExponentialBackOffPolicy prevents retry storms
- RetryListener emits metrics and observability signals
The single-item recovery cycle:
- When a chunk write fails, Spring Batch rolls back the chunk
- Then re-reads each item one at a time to isolate the bad row
- Good items succeed individually; bad item is skipped (if configured) or fails the step
- Processors must be idempotent — they may run twice for the same input
`noRollback` and `processorTransactional(false)`:
noRollback(ValidationException.class)— declares an exception expected and benignprocessorTransactional(false)— processor outputs not rolled back- Together they refine the rollback contract
The hard problem — non-transactional side effects:
- Emails, API calls, Kafka publishes are NOT undone by rollback
- Move them to a separate step that runs after success
- Or use the outbox pattern — write a row inside the chunk transaction, dispatch from a separate step
Anti-patterns to call out:
skipLimit(Integer.MAX_VALUE)— silent data corruptionskip(Exception.class)— masks real bugs- Retry without backoff — compounds the failure
- Retry on non-idempotent processors — duplicate side effects
In an interview I'd emphasize the single-item recovery cycle and the idempotency requirement — those are what separate practitioners from rote knowledge.
Spring Batch Retry and Skip Logic for Fault-Tolerant Jobs
Direct Answer
Spring Batch provides built-in retry and skip policies on chunk steps. Retry re-attempts processing or writing for a configured exception type up to a limit before failing — appropriate for transient failures (deadlock, network blip). Skip silently discards items that cause specified exceptions up to a tolerance count — appropriate for bad records (parse error, validation). Together with SkipListener and RetryListener they let you build fault-tolerant pipelines that survive dirty data and infrastructure flaps without aborting the entire batch run.
Common Mistakes & Pitfalls
Applying skip to write-phase exceptions without considering that a failed write rolls back the entire chunk — Spring Batch then re-reads items one at a time to isolate the bad row, which surprises many candidates
Check your understanding
Answer these without looking back at the article.
- How does Spring Batch handle a skip exception that occurs during a write when an entire chunk needs to be rolled back?
- Can you combine retry and skip on the same step, and if so, what is the order of precedence?
- How would you test retry behavior in a Spring Batch step without actually triggering real transient failures?
- Why is idempotency required for processors when fault tolerance is enabled?
Related interview prep categories
1Looking for a structured roadmap?
Every module on this page is also part of the full Java backend interview track.