一、前言
用过Spring Retry重试框架的都知道,它和Spring数据库事务一样都是基于AOP切面实现的,那如果两者同时在一个方法上使用会怎么样哪?下面写了一个栗子
@Override
@Retryable(value = { Exception.class }, maxAttempts = 3, backoff = @Backoff(delay = 3000L, multiplier = 1.2))
@Transactional(rollbackFor = Exception.class)
public void handle(Student student) {
System.out.println("正在尝试更新...");
this.updateById(student);
throw new RuntimeException("数据库操作异常!");
}
二、结果分析
1.执行结果
正在尝试更新...
正在尝试更新...
正在尝试更新...
java.lang.RuntimeException: 数据库操作异常!
...
2.时序图
下面是调用过程的简易时序图,依次调用
AnnotationAwareRetryOperationsInterceptor
、RetryOperationsInterceptor
、RetryTemplate
、TransactionInterceptor
,重试操作在RetryTemplate#doExecute
实现,MethodInterceptor
采用后进先出的栈调用规则。
3.源码阅读
下面仅是甩了根绳头,能不能滤清就看你自己了😛
- Spring Retry
org.springframework.retry.annotation.EnableRetry
==>org.springframework.retry.annotation.RetryConfiguration
- AOP Transaction
EnableTransactionManagement
==>org.springframework.transaction.annotation.TransactionManagementConfigurationSelector
==>org.springframework.transaction.annotation.ProxyTransactionManagementConfiguration