您的位置:首页技术文章
文章详情页

浅谈spring的重试机制无效@Retryable@EnableRetry

【字号: 日期:2023-08-13 14:11:26浏览:17作者:猪猪

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')@SpringBootApplicationpublic 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;@Servicepublic 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

浅谈spring的重试机制无效@Retryable@EnableRetry

可以看到,转账操作一共执行了3次,最后执行了回调方法。

至此Springboot整合Spring Retry的步骤已经完成,测试也非常成功!

有可以改进的地方希望诸位同学不要吝惜笔墨,加以指正,万分感谢!

以上这篇浅谈spring的重试机制无效@Retryable@EnableRetry就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持好吧啦网。

标签: Spring
相关文章: