淺談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的坑,就是方法內(nèi)部調(diào)用,會使aspect增強失效,那么retry當(dāng)然也會失效。
例如
public class demo {
public void A() {
B();
}
@Retryable(Exception.class)
public void B() {
throw new RuntimeException("retry...");
}
}
這種情況B()不會重試。
補充知識:Springboot整合Spring Retry實現(xiàn)重試機制
在項目開發(fā)過程中,經(jīng)常會有這樣的情況:第一次執(zhí)行一個操作不成功,考慮到可能是網(wǎng)絡(luò)原因造成,就多執(zhí)行幾次操作,直到得到想要的結(jié)果為止,這就是重試機制。
Springboot可以通過整合Spring Retry框架實現(xiàn)重試。
下面講一下在之前新建的ibatis項目基礎(chǔ)上整合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和實現(xiàn)類RetryServiceImpl
重試接口:
public interface RetryService {
void retryTransferAccounts(int fromAccountId, int toAccountId, float money) throws Exception;
}
接口實現(xiàn)類:
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("回調(diào)方法執(zhí)行?。?!");
}
}
@Retryable:標(biāo)記當(dāng)前方法會使用重試機制
value:重試的觸發(fā)機制,當(dāng)遇到Exception異常的時候,會觸發(fā)重試
maxAttempts:重試次數(shù)(包括第一次調(diào)用)
delay:重試的間隔時間
multiplier:delay時間的間隔倍數(shù)
maxDelay:重試次數(shù)之間的最大時間間隔,默認(rèn)為0,如果小于delay的設(shè)置,則默認(rèn)為30000L
@Recover:標(biāo)記方法為回調(diào)方法,傳參與@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

可以看到,轉(zhuǎn)賬操作一共執(zhí)行了3次,最后執(zhí)行了回調(diào)方法。
至此Springboot整合Spring Retry的步驟已經(jīng)完成,測試也非常成功!
有可以改進的地方希望諸位同學(xué)不要吝惜筆墨,加以指正,萬分感謝!
以上這篇淺談spring的重試機制無效@Retryable@EnableRetry就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
JavaSE API實現(xiàn)生成隨機數(shù)的2種方法(Random類和Math類的Random方法)
本文主要介紹了JavaSE API實現(xiàn)生成隨機數(shù)的2種方法,主要包括Random類和Math類的random方法都可以用來生成隨機數(shù),具有一定的參考價值,感興趣的可以了解一下2023-10-10
詳解log4j-over-slf4j與slf4j-log4j12共存stack overflow異常分析
這篇文章主要介紹了詳解log4j-over-slf4j與slf4j-log4j12共存stack overflow異常分析,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
Java instanceof關(guān)鍵字的的進一步理解
這篇文章主要介紹了Java instanceof關(guān)鍵字的的進一步理解,本文用一些實例講解了instanceof操作符的一些知識,需要的朋友可以參考下2015-03-03
如何實現(xiàn)java8 list按照元素的某個字段去重
這篇文章主要介紹了如何實現(xiàn)java8 list按照元素的某個字段去重,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,,需要的朋友可以參考下2019-06-06

