Spring Retry

Spring Retry

0 Comments

Spring Retry provides the ability to automatically re-invoke a failed operation. This is helpful when errors may be transient in nature. For example, a momentary network glitch, network outage, server down, or deadlock.

You can configure the spring-retry module using annotations. You can define the retry limits, fallback methods, etc.

In this post, you will learn how to use the spring-retry module.

Maven Dependencies

To use spring-retry in your application, you need the following dependencies in pom.xml file.

pom.xml

<dependency>
   <groupId>org.springframework.boot</groupId> 
   <artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>1.3.1</version>
</dependency>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-aspects</artifactId>
    <version>5.3.9</version>
</dependency>

<dependency>
   <groupId>org.projectlombok</groupId>
   <artifactId>lombok</artifactId>
   <optional>true</optional>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>

Spring Retry Example

I will demonstrate a service implementation with a method that throws an exception in case of a failure.  In such a case of exception, Spring retries to invoke the method 3 times.

In those 3 retry attempts, if a successful response is received from the method, then the response is returned to the caller. Ese a standard fallback method is called.

Defining the Interface

The code for the RetryService interface is this.

RetryService

package guru.springframework;

import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Retryable;

public interface RetryService {

    @Retryable(value = {CustomRetryException.class}, maxAttempts = 3, backoff = @Backoff(200))
    public String retry() throws CustomRetryException;
}

The @Retrayable annotation in Line 8 tells Spring that if we get CustomRetryException from the method call, then the method call should be retried 3 times with an interval of 2 seconds before sending the response.

Note: The value attribute in Line 8 tells Spring retry to act if the method throws CustomRetryException. Also the default value of maxAttempts is 3.

The code for the Implementation class is this.

RetryServiceImpl.java

@Slf4j
@Service
public class RetryServiceImpl implements RetryService {

    @Override
    public String retry() throws CustomRetryException {
        log.info("Throwing CustomRetryException in method retry");
        throw new CustomRetryException("Throw custom exception");
    }

    @Recover
    public String recover(Throwable throwable) {
        log.info("Default Retry servive test");
        return "Error Class :: " + throwable.getClass().getName();
    }
}

In Line 11, the @Recover annotation indicates that if you don’t get any success response after 3 retry, this fallback method will get called.

This is the code for the main class.

SpringRetryApplication.java

package guru.springframework;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;

@EnableRetry
@SpringBootApplication
public class SpringRetryApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringRetryApplication.class, args);
	}

}

You need to add @EnableRetry annotation to enable retry.

Test the Application

The code for the SpringRetryApplicationTest is this.

SpringRetryApplication.java

package guru.springframework;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

@Slf4j
@SpringBootTest
public class SpringRetryApplicationTest {

    @Autowired
    RetryService retryService;

    @Test
    public void sampleRetryService() {
        try {
            final String message = retryService.retry();
            log.info("message = " + message);
        } catch (CustomRetryException e) {
            log.error("Error while executing test {}", e.getMessage());
        }
    }
}

On Running the Test case, you will see the following output.

Spring Retry console output

Here we get an exception in the backend and then spring retries the same method 3 times as specified. Also, you get fallback response after the retry limit is reached every time we are throwing CustomRetryException.

Summary

The spring-retry module is very helpful to automatically retry a failed operation by replacing itself with having a loop and breaking it once the limit is reached. This feature also comes in handy when you integrate with external APIs and need a robust fail-safe system that can handle system downtime or network downtime.

You can find the source code of this post here on Github.

About SFG Contributor

Staff writer account for Spring Framework Guru

    You May Also Like

    Leave a Reply

    Your email address will not be published. Required fields are marked *

    This site uses Akismet to reduce spam. Learn how your comment data is processed.