1. 程式人生 > 實用技巧 >Springboot整合Spring Retry實現重試機制

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的步驟已經完成,測試也非常成功!