基于返回值重试详解
快速开始
大多数场景中的重试机制依赖于异常触发,但在某些依赖方法返回结果进行业务判断的场景下,基于异常并非最佳选择。因此,从版本 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;
}
}