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

 更新时间:2020年09月18日 10:28:43   作者:Singlerr  
这篇文章主要介绍了浅谈spring的重试机制无效@Retryable@EnableRetry,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

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的步骤已经完成,测试也非常成功!

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

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

相关文章

  • maven 删除下载失败的包的方法

    maven 删除下载失败的包的方法

    本文介绍了当Maven包报红时,使用删除相关文件的方法来解决该问题,具有一定的参考价值,感兴趣的可以了解一下
    2023-09-09
  • springboot项目编译提示无效的源发行版17解决办法

    springboot项目编译提示无效的源发行版17解决办法

    这篇文章主要给大家介绍了关于springboot项目编译提示无效的源发行版17解决办法,这个错误意味着你的Spring Boot项目正在使用Java 17这个版本,但是你的项目中未配置正确的Java版本,需要的朋友可以参考下
    2023-06-06
  • Servlet机制Pushlet原理及用法详解

    Servlet机制Pushlet原理及用法详解

    这篇文章主要介绍了Servlet机制Pushlet原理及用法详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-10-10
  • Java包装类的概述与应用

    Java包装类的概述与应用

    包装类使用起来非常方便,但是没有对应的方法来操作这些基本数据类型,可以使用一个类,把基本类型的数据装起来,在类中定义一些方法,我们可以使用类中的方法来操作这些基本类型的数据,这篇文章主要给大家介绍了关于Java包装类的相关资料,需要的朋友可以参考下
    2022-04-04
  • 浅谈System.getenv()和System.getProperty()的区别

    浅谈System.getenv()和System.getProperty()的区别

    这篇文章主要介绍了System.getenv()和System.getProperty()的区别,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-06-06
  • 从面试中的问题分析ThreadLocal

    从面试中的问题分析ThreadLocal

    这篇文章主要介绍了从面试中的问题分析ThreadLocal,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,下面我们来一起学习一下吧
    2019-06-06
  • Apache Commons Config管理配置文件核心功能使用

    Apache Commons Config管理配置文件核心功能使用

    这篇文章主要为大家介绍了Apache Commons Config管理和使用配置文件核心深入探索,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • Java实现高效随机数算法的示例代码

    Java实现高效随机数算法的示例代码

    这篇文章主要介绍了Java实现高效随机数算法的示例代码,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2019-02-02
  • 详解java内部类的访问格式和规则

    详解java内部类的访问格式和规则

    在本文里我们给大家详细分享了关于java内部类的访问格式和规则知识点内容,有兴趣的朋友们学习下。
    2018-10-10
  • Java 实现栈的三种方式

    Java 实现栈的三种方式

    这篇文章主要介绍了栈:LIFO(后进先出),自己实现一个栈,要求这个栈具有push()、pop()(返回栈顶元素并出栈)、peek() (返回栈顶元素不出栈)、isEmpty()这些基本的方法,需要的朋友可以参考下
    2020-12-12

最新评论