Implementing Robust Business Retry with Spring AOP and Annotations

This article explains how to implement a flexible business retry mechanism in Spring using custom annotations and AOP, covering the rationale, code examples for the @Retry annotation, RetryAspect, transaction considerations, and alternative Spring Retry library integration.

Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Spring Full-Stack Practical Cases
Implementing Robust Business Retry with Spring AOP and Annotations

Environment: Spring 5.3.23

1. Introduction

In software development, business retry is a common requirement to ensure correctness and reliability when operations fail. Spring AOP provides a powerful way to implement efficient and reliable retry handling.

2. Why Retry?

Improve system reliability : Network delays, service failures, or timeouts can cause request failures; retries increase reliability.

Ensure data consistency : In financial or e‑commerce systems, a failed operation may lead to inconsistent data; retries help maintain consistency.

Optimize user experience : Allowing retries gives users a tolerance for transient errors.

Prevent occasional mistakes : Simple input or operation errors can be corrected by retrying.

3. Retry Implementation

By combining a custom annotation with AOP, we can create a flexible retry mechanism. First, define the @Retry annotation:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface Retry {
    // Number of retry attempts
    int nums() default 3;
}

Next, implement an aspect that intercepts methods annotated with @Retry:

@Aspect
public class RetryAspect {
    @Around("@annotation(retry)")
    public Object retry(ProceedingJoinPoint pjp, Retry retry) throws Throwable {
        int maxRetries = retry.nums();
        int numAttempts = 0;
        RuntimeException rt;
        do {
            numAttempts++;
            try {
                return pjp.proceed();
            } catch (RuntimeException ex) {
                System.err.printf("Retry %d...%n", numAttempts);
                rt = ex;
                // Sleep 1 second before next retry
                TimeUnit.SECONDS.sleep(1);
            }
        } while (numAttempts <= maxRetries);
        // All retries exhausted, rethrow exception
        throw rt;
    }
}

Testing the retry logic:

public class UserService {
    @Retry
    public void save(int a) {
        if (a == 3) {
            throw new RuntimeException("参数错误");
        }
        System.out.println("保存成功");
    }
}

Running the test produces:

发生异常,进行重试
发生异常,进行重试
发生异常,进行重试
发生异常,进行重试
Exception in thread "main" java.lang.RuntimeException: 参数错误

The first call fails and triggers three retries before the exception is finally thrown.

4. Working with Transactions

If the business method runs within a transaction, each retry should execute in a new transaction to avoid stale reads under repeatable‑read isolation. Adding @Order(-1) to the RetryAspect ensures it runs before the transaction aspect:

@Aspect
@Order(-1)
public class RetryAspect {
}

Alternatively, Spring provides a dedicated spring-retry library that can be added via Maven:

<dependency>
    <groupId>org.springframework.retry</groupId>
    <artifactId>spring-retry</artifactId>
    <version>${spring-retry.version}</version>
</dependency>

That library offers extensive retry capabilities.

End of article.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

JavaaopspringRetryannotations
Spring Full-Stack Practical Cases
Written by

Spring Full-Stack Practical Cases

Full-stack Java development with Vue 2/3 front-end suite; hands-on examples and source code analysis for Spring, Spring Boot 2/3, and Spring Cloud.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.