淺談spring的重試機(jī)制無效@Retryable@EnableRetry
spring-retry模塊支持方法和類、接口、枚舉級(jí)別的重試
方式很簡單,引入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增強(qiáng),所有會(huì)有aspect的坑,就是方法內(nèi)部調(diào)用,會(huì)使aspect增強(qiáng)失效,那么retry當(dāng)然也會(huì)失效。
例如
public class demo { public void A() { B(); } @Retryable(Exception.class) public void B() { throw new RuntimeException("retry..."); } }
這種情況B()不會(huì)重試。
補(bǔ)充知識(shí):Springboot整合Spring Retry實(shí)現(xiàn)重試機(jī)制
在項(xiàng)目開發(fā)過程中,經(jīng)常會(huì)有這樣的情況:第一次執(zhí)行一個(gè)操作不成功,考慮到可能是網(wǎng)絡(luò)原因造成,就多執(zhí)行幾次操作,直到得到想要的結(jié)果為止,這就是重試機(jī)制。
Springboot可以通過整合Spring Retry框架實(shí)現(xiàn)重試。
下面講一下在之前新建的ibatis項(xiàng)目基礎(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、在啟動(dòng)類中加入重試注解@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和實(shí)現(xiàn)類RetryServiceImpl
重試接口:
public interface RetryService { void retryTransferAccounts(int fromAccountId, int toAccountId, float money) throws Exception; }
接口實(shí)現(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)前方法會(huì)使用重試機(jī)制
value:重試的觸發(fā)機(jī)制,當(dāng)遇到Exception異常的時(shí)候,會(huì)觸發(fā)重試
maxAttempts:重試次數(shù)(包括第一次調(diào)用)
delay:重試的間隔時(shí)間
multiplier:delay時(shí)間的間隔倍數(shù)
maxDelay:重試次數(shù)之間的最大時(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、啟動(dòng)ibatis項(xiàng)目進(jìn)行測試,在瀏覽器地址欄輸入:http://localhost:8080/retry/transfer
可以看到,轉(zhuǎn)賬操作一共執(zhí)行了3次,最后執(zhí)行了回調(diào)方法。
至此Springboot整合Spring Retry的步驟已經(jīng)完成,測試也非常成功!
有可以改進(jìn)的地方希望諸位同學(xué)不要吝惜筆墨,加以指正,萬分感謝!
以上這篇淺談spring的重試機(jī)制無效@Retryable@EnableRetry就是小編分享給大家的全部內(nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
springboot項(xiàng)目編譯提示無效的源發(fā)行版17解決辦法
這篇文章主要給大家介紹了關(guān)于springboot項(xiàng)目編譯提示無效的源發(fā)行版17解決辦法,這個(gè)錯(cuò)誤意味著你的Spring Boot項(xiàng)目正在使用Java 17這個(gè)版本,但是你的項(xiàng)目中未配置正確的Java版本,需要的朋友可以參考下2023-06-06淺談System.getenv()和System.getProperty()的區(qū)別
這篇文章主要介紹了System.getenv()和System.getProperty()的區(qū)別,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06Apache?Commons?Config管理配置文件核心功能使用
這篇文章主要為大家介紹了Apache?Commons?Config管理和使用配置文件核心深入探索,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12Java實(shí)現(xiàn)高效隨機(jī)數(shù)算法的示例代碼
這篇文章主要介紹了Java實(shí)現(xiàn)高效隨機(jī)數(shù)算法的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2019-02-02