关于缓存:聊聊缓存布尔值踩到的坑

47次阅读

共计 1464 个字符,预计需要花费 4 分钟才能阅读完成。

前言

有这么一个业务场景:部门 A 服务要应用部门 B 服务的业务数据,部门 A 服务应用部门 B 服务的业务数据前置条件是 B 部门必须要给 A 受权。B 部门的受权和业务数据分属为不同服务。其申请流程如下


因为 A 的鉴权信息的申请值是固定的,因而鉴权后果大概率也是固定值。过后 B 部门的业务服务开发共事,为了提高效率。就加了缓存,即 B 的业务服务会将 A 的鉴权后果缓存起来。过后写法形如下

 private final LoadingCache<String,Boolean> checkSvcCache = Caffeine
            .newBuilder().maximumSize(Constants.MAX_SIZE)
            .expireAfterWrite(Conastants.EXPIRE, TimeUnit.DAYS)
            .build(key -> loadCache(key));

    @Nullable
    private Boolean loadCache(@NonNull String key) {if(key.contains(Constant.UNDER_LINE)){
            try {String[] arr = key.split(Constant.UNDER_LINE);
                Integer ak = Integer.parseInt(arr[0]);
                String sk = arr[1];
                RPCResult<Boolean> result = authService.checkSvc(ak, sk);
                if(result.getSuccess()){Boolean data = result.getData();
                    return data;
                }
                return false;
            } catch (Exception e) {log.error("{}",e);
            }
        }
        return false;
    }

思考

大家看下上述代码块的写法有没有问题?

粗看貌似没啥问题,但理论是有点小问题的。当进行近程调用时,如果出现异常,此时布尔值会返回 false。这样就可能把正确的后果给覆盖了,比方明明都按约定的 ak,sk 传值了,后果返回鉴权失败。

修复

那要如何修复?扯一点哲学货色,这个世界不是非黑即白,其实可能还存在灰色地带。布尔值在 java 的世界中,也不是就只有 true 或者 false,当布尔值为包装类时,他还有一种状态是 null。因而能够批改为

@Nullable
    private Boolean loadCache(@NonNull String key) {if(key.contains(Constant.UNDER_LINE)){
            try {String[] arr = key.split(Constant.UNDER_LINE);
                Integer ak = Integer.parseInt(arr[0]);
                String sk = arr[1];
                RPCResult<Boolean> result = authService.checkSvc(ak, sk);
                if(result.getSuccess()){Boolean data = result.getData();
                    return data;
                }
                return false;
            } catch (Exception e) {log.error("{}",e);
            }
        }
        return null;
    }

但这样改就没问题了吗,其实还是有问题,因为 null 值也不是正确后果。但咱们能够利用 null 来额定做一些异样兜底。比方呈现 null 时,就是有问题了,咱们能够对 A 进行敌对的提醒,而非返回鉴权失败,也便于提前裸露问题,而下次申请进来时,缓存会因为值为 null,再次触发近程调用

总结

异样流程思考很重要。。。

正文完
 0