Springboot整合Spring Retry实现重试机制

Springboot整合Spring Retry实现重试机制

树冢
2021-09-03 / 0 评论 / 37 阅读 / 正在检测是否收录...

在项目开发过程中,经常会有这样的情况:第一次执行一个操作不成功,考虑到可能是网络原因造成,就多执行几次操作,直到得到想要的结果为止,这就是重试机制。
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
kt3unrja.png
可以看到,转账操作一共执行了3次,最后执行了回调方法。
至此Springboot整合Spring Retry的步骤已经完成,测试也非常成功!

0

评论 (0)

取消
百大云