浅谈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
猜你喜欢
- 简介在实现登录功能时,一般为了安全都会设置验证码登录,为了防止某个用户用特定的程序暴力破解方式进行不断的尝试登录。常见验证码分为图片验证码和
- 现在有一张订单表t_stockorder,其拥有id、code、client_id、merchandise_id、merchandise_n
- import java.io.BufferedReader; import java.io.IOException;  
- SpringCloud Gateway 简介SpringCloud Gateway 是 Spring Cloud 的一个全新项目,该项目是基
- MyBatis 是一款优秀的持久层框架,被各大互联网公司使用,本文使用Spring Boot整合Mybatis,并完成CRUD操作。为什么要
- 概述什么是动态编程?动态编程解决什么问题?Java中如何使用?什么原理?如何改进?(需要我们一起探索,由于自己也是比较菜,一般深入不到这个程
- 摘要:想必大家做开发的时候都会用到下拉刷新的控件,现在各种第三方的下拉刷新控件不胜枚举。当然最NB的还是XListView。其他也有针对Gr
- 环境:VS2019+Qt5.121. CLR库安装 &nb
- 这节主要完成一些基本的增删改查以及Service、Dao和Action的抽取。1. Service层的抽取  
- java沙箱环境测试支付宝支付接口?准备工作,登陆支付宝开放平台,进入沙箱环境开放平台链接:https://developers.alipa
- 关闭 IDEA 的自动检查更新(截图idea 2020 2.x)idea 右下角会有这样的更新提示2. 关闭 idea 自动检查更新取消勾选
- 一、什么是Java事务通常的观念认为,事务仅与数据库相关。  
- 一.前言这一篇来看看 SpringIOC 里面的一个细节点 , 来简单看看 BeanDefinition 这个对象 , 以及有没有办法对其进
- 责任链模式责任链模式的定义:使多个对象都有机会处理请求,从而避免请求的发送者和接受者之间的耦合关系, 将这个对象连成一条链,并沿着这条链传递
- 工作中一直都是一个人奋战一人一个项目,使用maven管理,看这个也挺好,但是总感觉没有充分发挥maven的功能,于是研究了一下这个,网上关于
- 说明:本文记录如何在Idea下,利用Maven管理项目,并整合SSM(Spring + Spring MVC +Mybatis)框架,实现简
- jmap:Java内存映像工具jmap(Memory Map for Java)命令用于生成堆转储快照(一般称为heapdump或dump文
- 概述ArrayList是基于数组实现的,是一个动态数组,其容量能自动增长,类似于C语言中的动态申请内存,动态增长内存。ArrayList不是
- 在你的jar文件当前目录中建立一个bat文件:内容是:注意文件名要对应@echo offSTART "commandServer&
- 概述:Flutter 标签类控件大全ChipFlutter内置了多个标签类控件,但本质上它们都是同一个控件,只不过是属性参数不同而已,在学习