Skip to content

基于返回值重试详解

快速开始

大多数场景中的重试机制依赖于异常触发,但在某些依赖方法返回结果进行业务判断的场景下,基于异常并非最佳选择。因此,从版本 1.6.0 开始,系统新增了基于方法返回结果判断是否重试的能力,以支持更灵活的业务控制逻辑。

1 参数说明

参数描述默认值必须指定
retryIfResult当方法正常返回结果时,允许用户针对返回结果判断是否需要开启重试

1.1 retryIfResult

  • 作用:当方法正常返回结果时,允许用户针对返回结果判断是否需要开启重试。
  • 说明:这里注意了,如果存在嵌套重试,由于默认传播机制是Required, 即使内部的方法判断了需要重试但是重试是被外部的Retryable控制所以不会触发重试,这里如果需要外边触发重试,则需要对结果进行处理,外部重试需要感知到

2.2 代码示例与说明

2.2.1 retryIfResult

  • 假设我们基于结果判断是否等于RetryIfResult才进行重试
java
 @Retryable(scene = "localRetryWithIfResultLocalRemote", retryStrategy = RetryType.LOCAL_REMOTE, retryIfResult = NeedRetry.class)
    public OrderVo localRetryWithIfResultLocalRemote(String type) {
          OrderVo orderVo = new OrderVo();
          orderVo.setOrderId(type);
          return orderVo;
    }

    public static class NeedRetry implements RetryCondition {
        @Override
        public boolean shouldRetry(Object returnResult) {
            if (returnResult instanceof OrderVo orderVo) {
                return orderVo.getOrderId().equals("RetryIfResult");
            }

            return false;
        }
    }
  • 假设存在嵌套场景
java
 // 外部方法
@Retryable(scene = "localRetryWithPropagationRequired", retryStrategy = RetryType.LOCAL_REMOTE, retryIfResult = LocalRetryWithPropagationRequiredNeedRetry.class)
public boolean localRetryWithPropagationRequired(String params) {
    /**
     * 这里注意了,由于传播机制是Required, 这里会正常返回结果值,但是重试是被外部的Retryable控制,所以localRetryIfResultWithRequires不会触发重试
     * 这里如果需要外边触发重试,则需要对结果进行处理,外部重试需要感知到
     */
    OrderVo orderVo = localAndRemoteRetryHandler.localRetryIfResultWithRequires(params);
    if (orderVo.getOrderId().equals("RetryIfResult")) {
        // 这里抛异常也行 double i = 1 / 0;
        // 基于结果控制也行
        return false;
    }
    return false;
}
    
public static class LocalRetryWithPropagationRequiredNeedRetry implements RetryCondition {

@Override
public boolean shouldRetry(Object returnResult) {
    if (returnResult instanceof Boolean) {
        return !(Boolean) returnResult;
    }
    return false;
  }
}
  
// 内部方法
@Retryable(scene = "localRetryIfResultWithRequires", retryStrategy = RetryType.LOCAL_REMOTE, retryIfResult = NeedRetry.class)
public OrderVo localRetryIfResultWithRequires(String params) {
    System.out.println("local retry 方法开始执行");
    return new OrderVo(params, 1);
}

public static class NeedRetry implements RetryCondition {
    @Override
    public boolean shouldRetry(Object returnResult) {
        if (returnResult instanceof OrderVo orderVo) {
            return orderVo.getOrderId().equals("RetryIfResult");
        }

        return false;
    }
}