[Solved] Spring @Retryable annotation not working in spring boot application – Spring

by
Maya Patel
java spring spring-boot spring-retry

Quick Fix: Ensure that retryable exceptions are not caught and rethrown within the method annotated with @Retryable. Spring’s retry mechanism relies on detecting these exceptions to trigger retries.

The Problem:

A developer is attempting to implement a retry mechanism using Spring Retry in a Spring Boot application. However, the retry mechanism is not working as expected. The developer has added the necessary annotations and configured the retry parameters, but the method annotated with @Retryable is not being retried upon encountering an exception. The developer seeks guidance on identifying the missing components or incorrect configurations that may be hindering the retry mechanism from functioning properly.

The Solutions:

Solution 1: Exposing Exceptions from Retryable Method

The problem with the given code is that it’s catching all exceptions inside the getProductMetadata method, which prevents the Spring retry mechanism from detecting retryable exceptions. To make retries work, the method should throw retryable exceptions instead of handling them internally.

To resolve this issue, you can modify the code as follows:

@Retryable(retryFor = Exception.class, maxAttempts = 5, backoff = @Backoff(delay = 100))
public ProductResponse getProductMetadata(String sku, HandlerResult handlerResult) {
    HttpHeaders headers = new HttpHeaders();
    headers.add(HttpHeaders.CONTENT_TYPE, "application/json");

    String endpoint = getProductFetchMetadataEndpoint();

    ResponseEntity<String> response;

    try {
        response = restTemplate.getForEntity(endpoint, String.class);
    } catch (Exception ex) {
        // Rethrow the exception to trigger the retry mechanism
        throw ex;
    }

    ProductResponse metadataResponse;
    Gson gson = new Gson();
    try {
        metadataResponse = gson.fromJson(response.getBody(), ProductResponse.class);
    } catch (Exception e) {
        String errorMsg = String.format("Exception ProductResponse converting %s to map", response.getBody());
        log.info(errorMsg);
        HandlerResult.updateStatus(handlerResult, errorMsg, false);
        throw e; // Rethrow the exception to trigger the retry mechanism
    }

    return metadataResponse;
}

By rethrowing the exceptions instead of catching them, you allow the Spring retry mechanism to detect and handle the retryable exceptions appropriately.

Q&A

Why @Retryable is not working?

Check if you’re catching the exceptions inside the method, and throwing it.

How does Spring retry works?

Spring retry uses a proxy to detect/catch the exception outside.

Video Explanation:

The following video, titled "Unlock the Hidden Power of Spring Boot Retry - YouTube", provides additional insights and in-depth exploration related to the topics discussed in this post.

Play video

Eliminate CORS Issues: Single Jar Solution for React and Router (6.4) in Spring Boot App. Fast and Simple Development•1.6K views · 49:53 · Go to ...