浅谈spring的重试机制无效@Retryable@EnableRetry
作者:Singlerr 发布时间:2021-12-12 10:42:57
spring-retry模块支持方法和类、接口、枚举级别的重试
方式很简单,引入pom包
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>lastest</version>
</parent>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework.retry/spring-retry -->
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
<version>1.1.2.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.6</version>
</dependency>
然后在@Configuration注解的类中添加@EnableRetry
最后在想要重试的方法上添加@Retryable(Exception.class)
由于retry用到了aspect增强,所有会有aspect的坑,就是方法内部调用,会使aspect增强失效,那么retry当然也会失效。
例如
public class demo {
public void A() {
B();
}
@Retryable(Exception.class)
public void B() {
throw new RuntimeException("retry...");
}
}
这种情况B()不会重试。
补充知识:Springboot整合Spring Retry实现重试机制
在项目开发过程中,经常会有这样的情况:第一次执行一个操作不成功,考虑到可能是网络原因造成,就多执行几次操作,直到得到想要的结果为止,这就是重试机制。
Springboot可以通过整合Spring Retry框架实现重试。
下面讲一下在之前新建的ibatis项目基础上整合Spring Retry框架的步骤:
1、首先要在pom.xml配置中加入spring-retry的依赖:
<dependency>
<groupId>org.springframework.retry</groupId>
<artifactId>spring-retry</artifactId>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
</dependency>
2、在启动类中加入重试注解@EnableRetry。
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.retry.annotation.EnableRetry;
@EnableRetry //重试注解
@MapperScan("com.batis.mapper")
@SpringBootApplication
public class BatisApplication {
public static void main(String[] args) {
SpringApplication.run(BatisApplication.class, args);
}
}
3、新建重试接口RetryService和实现类RetryServiceImpl
重试接口:
public interface RetryService {
void retryTransferAccounts(int fromAccountId, int toAccountId, float money) throws Exception;
}
接口实现类:
import com.batis.mapper.AccountMapper;
import com.batis.model.Account;
import com.batis.service.RetryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
@Service
public class RetryServiceImpl implements RetryService {
@Autowired
private AccountMapper accountMapper;
@Transactional
@Retryable(value = Exception.class, maxAttempts = 3, backoff = @Backoff(delay = 3000, multiplier = 1, maxDelay = 10000))
@Override
public void retryTransferAccounts(int fromAccountId, int toAccountId, float money) throws Exception {
Account fromAccount = accountMapper.findOne(fromAccountId);
fromAccount.setBalance(fromAccount.getBalance() - money);
accountMapper.update(fromAccount);
int a = 2 / 0;
Account toAccount = accountMapper.findOne(toAccountId);
toAccount.setBalance(toAccount.getBalance() + money);
accountMapper.update(toAccount);
throw new Exception();
}
@Recover
public void recover(Exception e) {
System.out.println("回调方法执行!!!");
}
}
@Retryable:标记当前方法会使用重试机制
value:重试的触发机制,当遇到Exception异常的时候,会触发重试
maxAttempts:重试次数(包括第一次调用)
delay:重试的间隔时间
multiplier:delay时间的间隔倍数
maxDelay:重试次数之间的最大时间间隔,默认为0,如果小于delay的设置,则默认为30000L
@Recover:标记方法为回调方法,传参与@Retryable的value值需一致
4、新建重试控制器类RetryController
import com.batis.service.RetryService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/retry")
public class RetryController {
@Autowired
private RetryService retryService;
@RequestMapping(value = "/transfer", method = RequestMethod.GET)
public String transferAccounts() {
try {
retryService.retryTransferAccounts(1, 2, 200);
return "ok";
} catch (Exception e) {
return "no";
}
}
}
5、启动ibatis项目进行测试,在浏览器地址栏输入:http://localhost:8080/retry/transfer
可以看到,转账操作一共执行了3次,最后执行了回调方法。
至此Springboot整合Spring Retry的步骤已经完成,测试也非常成功!
有可以改进的地方希望诸位同学不要吝惜笔墨,加以指正,万分感谢!
来源:https://blog.csdn.net/xsgnzb/article/details/78780795
猜你喜欢
- 1. 每个编译单元(文件)都只能有一个public类。即每个编译单元都有单一的公共接口,用public类实现。此时,mian()就必须要包含
- 本文实例为大家分享了Unity Shader实现黑幕过场效果的具体代码,供大家参考,具体内容如下一、效果演示二、实现Shader:黑幕过场着
- Java-JDK * (AOP)使用及实现原理分析第一章:代理的介绍介绍:我们需要掌握的程度 * (理解) 基于反射机制掌握的程度:1.
- SpringBoot配置外部静态资源映射使用场景实际项目中,特别是前后端分离的项目,SpringBoot后台打包(jar包)后,以jar包形
- 这一篇主要是用来介绍关于C#中的XML序列化的问题,这个相信大家一定会经常使用它,特别是在WPF中,有时候我们需要将我们后台的数据保存在数据
- 嵌套表格,即在一张表格中的特定单元格中再插入一个或者多个表格,使用嵌套表格的优点在于能够让内容的布局更加合理,同时也方便程序套用。下面的示例
- 问题说明:IDEA编译的时候乱码,Build Output提示信息乱码�����。解决方案一:将Help—>Edit Cusuom V
- 本文实例为大家分享了Android实现图片点击放大的具体代码,供大家参考,具体内容如下在我的项目中,有点击图片banner后放大浏览的功能。
- 一、html代码 &n
- 一、Maven项目使用步骤一般包含两步,1)引入依赖 2)特定的 IDE 引入对应的插件1)在POM中引入依赖<!-- https:/
- 指定委托那些办理者处理任务节点,也就是只有此办理者才有操作此节点的操作权限1、直接指定流程图配置实现:在流程图属性栏设置Assignee属性
- 原文:http://it.deepinmind.com/java/2015/03/17/20-examples-of-date-and-ti
- 本文实例讲述了java实现MD5加密的方法。分享给大家供大家参考,具体如下:private String getMD5Str(String
- 上一篇讲完注解,这篇咱们科普一 * 解的其中一种用途——注解处理器(APT),文章会手把手的帮助大家学
- Java获取控制台输入的方法在学习网络编程中,有需要从控制台输入数据,进行两个线程之间的通信,其中,涉及到了读取控制台输入的两种不同的操作,
- 前言现在的项目一般是拆分成一个个独立的模块,当在其他项目中想要使用独立出来的这些模块,只需要在其pom.xml使用<dependenc
- 本文实例讲述了Java设计模式之工厂模式。分享给大家供大家参考,具体如下:一、 简单工厂先来思考一个问题。我们平时写程序时,会有这种情况,A
- kafka 架构原理大数据时代来临,如果你还不知道Kafka那就真的out了!据统计,有三分之一的世界财富500强企业正在使用K
- 最近在项目中,一个go服务给前端提供了一个接口,返回json格式数据,其中Int64字段会超出javascript Number可表示的最大
- 说明:以下的代码基于httpclient4.5.2实现。我们要使用java的HttpClient实现get请求抓取网页是一件比较容易实现的工