Spring @Retryable 和 @Recover

本文介绍了在Spring中使用@Retryable和@Recover时需要注意的事项。@Recover注解的方法需接收@Retryable捕获的异常作为第一个参数,并且返回值需与@Retryable方法一致。未正确使用@Recover可能导致无限重试。当超过最大重试次数,系统会执行RecoverAnnotationRecoveryHandler的相关方法。理解这两个注解的配合使用能防止重试机制导致的无限循环问题。
摘要由CSDN通过智能技术生成

@Retryable 和 @Recover 使用的时候 注意事项

  1. @Recover的注解的方法第一个参数需要是 @Retryable 所捕获的重试异常类型;必须是第一个参数
  2. @Recover注解的方法的 返回值必须 和 @Retryable注解的方法返回值一致

上面两条的原因见文章末尾

最近在使用@Retryable 注解时出现的问题 是 使用了 @Retryable 注解之后;指定了特定的异常进行异常重试机制;设置最大重试次数,当时只设置了@Retryable 注解;但是并没有配合使用 @Recover注解;然后 尽然发现会无限自动重试;大致看了一下;分析如下;如有错误请指出

代码

//当前类中只有 此注解'没有使用  '  @Recover 注解
@Retryable(maxAttempts = 5, value = RetryException.class, backoff = @Backoff(
            value = 2000L, multiplier = 1.5
    ))

查看发现 之所以 无限循环的原因因为没有设置 @Recover 注解;在本类中添加 @Recover 注解就好了;
具体分析的对不对; 只是我的测试

重试机制会走这个方法

org.springframework.retry.support.RetryTemplate#doExecute

代码抽出如下

//org.springframework.retry.support.RetryTemplate#doExecute 
//重点看这个代码的倒数第14行的中文注释处
protected <T, E extends Throwable> T doExecute(RetryCallback<T, E> retryCallback,
			RecoveryCallback<T> recoveryCallback, RetryState state)
			throws E, ExhaustedRetryException {
   

		RetryPolicy retryPolicy = this.retryPolicy;
		BackOffPolicy backOffPolicy = this.backOffPolicy;

		// Allow the retry policy to initialise itself...
		RetryContext context = open(retryPolicy, state);
		if (this.logger.isTraceEnabled()) {
   
			this.logger.trace("RetryContext retrieved: " + context);
		}

		// Make sure the context is available globally for clients who need
		// it...
		RetrySynchronizationManager.register(context);

		Throwable lastException = null;

		boolean exhausted = false;
		try {
   

			// Give clients a chance to enhance the context...
			boolean running = doOpenInterceptors(retryCallback, context);

			if (!running) {
   
				throw new TerminatedRetryException(
						"Retry terminated abnormally by interceptor before first attempt");
			}

			// Get or Start the backoff context...
			BackOffContext backOffContext = null;
			Object resource = context.getAttribute("backOffContext");

			if (resource instanceof BackOffContext) {
   
				backOffContext = (BackOffContext) resource;
			}

			if (backOffContext == null) {
   
				backOffContext = backOffPolicy.start(context);
				if (backOffContext != null) {
   
					context.setAttribute("backOffContext", backOffContext);
				}
			}

			/*
			 * We allow the whole loop to be skipped if the policy or context already
			 * forbid the first try. This is used in the case of external retry to allow a
			 * recovery in handleRetryExhausted without the callback processing (which
			 * would throw an exception).
			 */
			while (canRetry(retryPolicy, context) && !context.isExhaustedOnly()) {
   

				try {
   
					if (this.logger.isDebugEnabled(<
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值