美文网首页
spring-boot-starter-data-redis使用

spring-boot-starter-data-redis使用

作者: vayci | 来源:发表于2023-08-16 11:12 被阅读0次

问题说明

在开发过程中,某个方法上进行了以下注解,将返回数据缓存起来。

    @Cacheable(
            value = CacheKey.DEPT_ALL,
            unless="#result==null")

由于业务需要,在另一个Class中,调用某个方法时需要清除这个缓存,于是注解上:

    @CacheEvict(
            value = CacheKey.DEPT_ALL
     )

然而在调用缓存清除的方法时,发现缓存并没有清除,注解没生效。

问题排查

看网上有说法说对于缓存操作要放到同一个Java文件中,不能分开到两个类。但是这个说法一看感觉就不正确,于是进行源码分析排查。

定位到spring-boot-starter-data-redis的核心类 org.springframework.cache.interceptor.CacheInterceptor

可以排查到针对注解方法实现的操作位于org.springframework.cache.interceptor.CacheAspectSupport#execute()方法中

代码片段:

        // Collect any explicit @CachePuts
        collectPutRequests(contexts.get(CachePutOperation.class), cacheValue, cachePutRequests);

        // Process any collected put requests, either from @CachePut or a @Cacheable miss
        for (CachePutRequest cachePutRequest : cachePutRequests) {
            cachePutRequest.apply(cacheValue);
        }

        // Process any late evictions
        processCacheEvicts(contexts.get(CacheEvictOperation.class), false, cacheValue);

这里分别处理了缓存写入和缓存失效的相关操作。

分别断点查看调用缓存写入和缓存失效时操作的Redis Key值,发现缓存写入时,Key是"SimpleKey";而缓存失效时,Key是我方法传入的一堆参数。问题产生的原因就已经明确了,是因为写入和销毁的key值不一致,导致缓存没有销毁成功。

问题修复

查看@CacheEvict的文档里面对Key值说明:

Default is "", meaning all method parameters are considered as a key, unless a custom keyGenerator has been set.

不进行配置时,默认是将方法的所有参数作为key。

修复方案也比较简单了,由于这里对key值没有要求,是固定的缓存key。将注解的key加一个固定字符串即可。

        @Cacheable(
            value = CacheKey.DEPT_USER_COUNT,
            unless="#result==null",
            key="'ALL'")

    @CacheEvict(value = CacheKey.DEPT_USER_COUNT, key = "'ALL'")

总结:注解@CacheEvict失效,首先排查Key值与写入的Key值是否一致。

相关文章

网友评论

      本文标题:spring-boot-starter-data-redis使用

      本文链接:https://www.haomeiwen.com/subject/fvmkmdtx.html