@Retryable注解优雅的实现了异常重试,让我们的代码简洁而不失优雅,但是,不正确的使用会导致重试失败。

  1. 第一种情况, 我们在本类中调用set()方法,如果是直接调用的话则不会生效,这是spring 的通病了,我们需要做的是通过注入自身或者从IOC容器中拿自身bean对象来调用此方法。

@Retryable(value = Exception.class, maxAttempts = REDIS_RETRY, backoff = @Backoff(delay = REDIS_DELAY))
public <R>boolean set(String key, Map<String, R> value, RedisTemplate cache) {
    cache.opsForHash().putAll(key, value);
    return true;
}

2.当我们使用@Recover注解指定重试方法的时候我们需要将异常放在第一位,并且将Retryable中的所有参数复制进去,才能保证正确的调用get方法,其中所有的参数都是可以用的,这也是retry给我们提供的便利的地方,同时也是坑,一定要注意

@Retryable(recover = "get", value = Exception.class, maxAttempts = REDIS_RETRY, backoff = @Backoff(delay = REDIS_DELAY))
public String hget(String key, String item, RedisTemplate cache) {
    Object value = cache.opsForHash().get(key, item);
    if (value == null) {
        return null;
    }
    return value.toString();
}

@Recover
public String get(Exception e, String key, String item, RedisTemplate cache) {
    Object value = cache.opsForHash().get(key, item);
    if (value == null) {
        return null;
    }
    return value.toString();
}

3.异常是一定要作为参数的,不然也不会生效,retry将所有的可以用到的参数都给了我们,提供便利的同时也必须遵守规则