小言_互联网的博客

Spring-retry重试框架怎么用?看这里

259人阅读  评论(0)

一. 问题

近日有学生问壹哥,应该怎样理解【阿里巴巴开发规约中提到的乐观锁至少要重试三次】的规定,为了让大家更好的理解这一点,壹哥先来引用一下阿里巴巴开发规约中的相关规定。

强制】并发修改同一记录时,避免更新丢失,需要加锁。要么在应用层加锁,要么在缓存加锁,要么在数据库层使用乐观锁,使用 version 作为更新依据。

说明:如果每次访问冲突概率小于 20%,推荐使用乐观锁,否则使用悲观锁。乐观锁的重试次数不得小于 3 次。

二. 解答

对于这个问题,壹哥是这么认为的。【乐观锁采用CAS机制,在事务的最后才会根据version来判断事务是否能够提交成功。很多时候仅仅只是因为其他的事务快一步更新了version,就导致整个事务提交失败,这样给用户的体验并不好,所以咱们要在这里让事务重试几次,提升用户的使用体验】。

其实重试的方式有很多,今天壹哥来给大家介绍一款Spring自带的重试框架 【spring-retry】

三. spring-retry 框架介绍

2.1 spring-retry框架是什么

spring-retry是spring提供的一个重试框架,它通过几个注解就可以优雅的实现重试的功能。

2.2 怎样使用spring-retry框架

导入依赖


  
  1. <dependency>
  2. <groupId>org.springframework.retry </groupId>
  3. <artifactId>spring-retry </artifactId>
  4. </dependency>

在主程序能够扫描到的类上,或者直接在主程序上添加@EnableRetry注解,开启重试。


  
  1. @SpringBootApplication
  2. @EnableRetry
  3. public class BankApplication {
  4. public static void main (String[] args) {
  5. SpringApplication.run(BankApplication .class, args);
  6. }
  7. }

在有可能需要重试的方法上添加注解。


  
  1. @Transactional
  2. @Retryable(value = { RetryException.class }, maxAttempts = 3, backoff = @Backoff(delay = 1000l, multiplier = 2,maxDelay = 10000l))
  3. // @Retryable 加上此注解 那么这个方法就有可能重试
  4. // value = { RetryException.class } 当方法中抛出RetryException异常就要重试
  5. // maxAttempts 最大重试的次数
  6. // Backoff 回避策略
  7. // delay 第一次重试的延迟时间
  8. // multiplier 下一次重试的延迟时间,公式为:上一次delay* multiplier
  9. // maxDelay:最长延迟时间
  10. public void getMoney (String ano, BigDecimal money){
  11. // 1 查询账号是否存在
  12. TbAccount tbAccount = accountMapper.selectByPrimaryKey(ano);
  13. if (tbAccount == null) {
  14. throw new AppException(ResponseEnum.ACCOUNT_NOT_FOUND);
  15. }
  16. // 2 余下额度是否够
  17. if(tbAccount.getAccountMoney().compareTo(money)< 0){
  18. throw new AppException(ResponseEnum.ACCOUNT_MONEY_NOT_ENOUTH);
  19. }
  20. // 3 更新取钱
  21. int count = accountMapper.updateMoney(ano, money, tbAccount.getVersion());
  22. if(count== 0){
  23. throw new RetryException( "");
  24. }
  25. System.out.println( "取钱成功");
  26. }

如果最大重试次数也重试完了,但还是失败的话,添加我们将要执行的逻辑。


  
  1. @Recover
  2. public void recover (RetryException e) {
  3. throw new AppException(ResponseEnum.ACCOUNT_EXCEPTION);
  4. }

四. 小结

到此,细心的同学应该已经能发现,spring-retry这个框架的底层原理其实就是aop的异常增强。当方法中抛出指定类型异常的时候,我们就给予一定次数的重试。

另外,重试的业务场景也不一定就局限在乐观锁上面,其他很多业务场景也需要使用到重试。

比如说:

  • 由于网络波动或者系统太忙,造成远程调用失败需要重试;
  • 秒杀时使用分布式锁时,当一个事务锁住商品,导致其他的购买请求不能正常进行时也需要重试。

转载:https://blog.csdn.net/syc000666/article/details/127682263
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场