Spring Batch — Retry Logic Deep Dive
Retries are a fundamental technique for building resilient batch processes. Some failures are transient (network blips, temporary DB locks, remote API hiccups) and recoverable by retrying. This guide explains when and how to use retries in Spring Batch, configuration patterns, backoff strategies, listeners and metrics, pitfalls like non-idempotency and transaction boundaries, and production best practices.
๐ Why Retry?
- Transient infrastructure errors (DB deadlocks, network timeouts)
- Intermittent external API failures
- Short-lived resource contention
Rule of thumb: Retry for transient problems, not for deterministic data validation errors. If a retry won't change the outcome, don’t retry — skip or fail instead.
๐ง Two Ways to Retry in Spring Batch
Spring Batch supports retry at the step level using the faultTolerant() builder and also via Spring Retry (e.g. RetryTemplate) for custom code paths.
| Approach | Where to use | Pros | Cons |
|---|---|---|---|
| Spring Batch faultTolerant().retry() | Reader / Processor / Writer failures in chunk steps | Integrated with chunk semantics, skip/retry metrics, listeners | Less flexible than RetryTemplate for ad-hoc retries |
| Spring Retry / RetryTemplate | Custom service calls inside processor/writer or outside Batch | Very flexible: policies, backoff, recoverers | Requires manual integration with Batch semantics |
⚙️ Example: Retry Configuration with faultTolerant()
@Bean
public Step chunkStep() {
return stepBuilderFactory.get("chunkStep")
.chunk(10)
.reader(reader())
.processor(processor())
.writer(writer())
.faultTolerant()
.retry(TransientDataAccessException.class) // retry on these exceptions
.retryLimit(3) // max attempts
.backOffPolicy(new FixedBackOffPolicy() {{ setBackOffPeriod(2000L); }})
.retryPolicy(new SimpleRetryPolicy(3, Collections.singletonMap(SomeRemoteException.class, true)))
.build();
}
⏱ Backoff Strategies
ExponentialBackOffPolicy backoff = new ExponentialBackOffPolicy(); backoff.setInitialInterval(500L); backoff.setMultiplier(2.0); backoff.setMaxInterval(10_000L); faultTolerant() .retry(SomeTransientException.class) .backOffPolicy(backoff);
๐ Stateful vs Stateless Retry
/* Enable stateful retry */ // In Spring Retry you can use StatefulRetryOperationsInterceptor and configure a key RetryTemplate retryTemplate = new RetryTemplate(); // configure stateful policy / recovery
๐งฉ RetryListener Example
public class LoggingRetryListener implements RetryListener {
@Override
public boolean open(RetryContext context, RetryCallback callback) {
return true;
}
@Override
public void close(RetryContext context, RetryCallback callback, Throwable throwable) {
// After all retry attempts
}
@Override
public void onError(RetryContext context, RetryCallback callback, Throwable throwable) {
System.out.println("Retry attempt: " + context.getRetryCount() + " due to " + throwable.getMessage());
}
}
๐ RetryTemplate Example
RetryTemplate template = new RetryTemplate();
SimpleRetryPolicy policy = new SimpleRetryPolicy(3);
template.setRetryPolicy(policy);
ExponentialBackOffPolicy backoff = new ExponentialBackOffPolicy();
backoff.setInitialInterval(500);
backoff.setMultiplier(2.0);
template.setBackOffPolicy(backoff);
String result = template.execute(context -> {
return remoteService.call();
}, context -> {
return "fallback";
});
๐งช Testing Retry Logic
@Test
void testRetryOnTransientException() {
when(remoteService.call())
.thenThrow(new TransientException())
.thenThrow(new TransientException())
.thenReturn("OK");
// assert result == "OK"
}
๐ Related Spring Batch Fault-Tolerance Guides
Build resilient Spring Batch jobs by exploring related concepts such as skip policies, processing logic, conditional flows, and performance optimization strategies.
๐งฑ Spring Batch Core Components
Understand how retry logic integrates with Job, Step, ItemReader, ItemProcessor, and ItemWriter.
๐ซ Skip Policy & Error Handling
Learn when to retry a failed item versus skipping it to keep batch jobs running smoothly.
๐ Spring Batch ItemProcessor Example
Apply retry logic during validation and transformation failures inside ItemProcessor implementations.
๐ฅ CSV to Database with Spring Batch
Handle transient database failures gracefully while importing CSV data using retry mechanisms.
๐ Conditional Flow in Spring Batch Jobs
Control job execution paths based on retry exhaustion and step exit statuses.
๐งต Multithreaded Step
Understand retry behavior and thread-safety concerns when executing steps in parallel.
⚙️ Spring Batch Tasklet
Implement custom retry logic for non-chunk-oriented batch steps using Tasklets.