spring cache 拓展
spring cache 的一大缺陷是无法对集合缓存操作
例如:信箱功能
@Cacheable(value="mailCache",key="#uid+'list'") public List<Mail> getMails(Integer uid); @Cacheable(value = "mailCache", key = "#id") public Mail getMail(Integer id); @CacheEvict(value = "mailCache", key = "#mail.uid + 'list'") @CachePut(value = "mailCache", key = "#mail.id") public Mail update(Mail mail); @CacheEvict(value = "mailCache", key = "#mail.uid + 'list'") public Mail saveMail(Mail mail);
这4个接口是一个典型的数据操作接口,get、update、save、findList
其中的缓存的处理分为2部分:实体缓存(get、update、save)、集合缓存(findList)
1、执行get 方法把Mail实体缓存起来
2、执行getMail方法把Mail集合缓存起来
3、执行update更新Maill实体缓存并且清除Mail的集合缓存
4、执行save清除Mail的集合缓存
以上4点的问题所在:
1、save操作无法缓存Mail(因为缺少主键ID,Spring Cache限定了只能从参数中解析key)
2、save、update只能清除Mail的集合缓存,降低了集合缓存的利用率
为此,拓展Spring AOP Cache 添加annotation:@CacheUpdate、@CacheDelete、@CacheSave
1、在@CacheSave注解下,通过方法的返回值生成key,并且把返回值添加至集合Cache中。并且把返回值缓存起来
2、在@CahceUpdate注解下,通过参数生成key,并且把返回值更新至集合Cache中
3、在@CacheDelete注解下,通过参数生成key,并且从集合Cache中移除该实体
4、在@CacheDelete注解下,可以缓存住删除操作
以上3点做法的缺陷:
1、@CacheSave不保证顺序
2、@CacheUpdate需要自行考虑是否适用。例如:
@Cacheable(value="mailCache",key="#uid+'list'") public List<Mail> getUnReadMails(Integer uid,boolean read){ return find("select * from Mail where uid = ? and read = ?",uid,read); }
之前的getMail方法,参数只有uid,而uid是一个不变值。所以Mail实体update操作不会改变uid
而getUnReadMails多了一个参数read,Mail实体update是有可能update read从而影响getUnreadMails的缓存,导致不一致(这里的getUnreadMails方法就有可能多出/少一个实体,虽然@CacheUpdate有更新到最新的Mail,但是getUnreadMails的集合会多出这个)
解决办法是正确的使用@CacheDelete和@CacheUpdate
例如:上面这个例子应该在update方法上面加上一个@CacheDelete用于移除掉符合条件的实体
具体的代码因为还缺少同步、测试所以暂时不上传
上一篇: jquery怎么判断当前元素是第几个
下一篇: 浅谈NVM如何安装和管理多个Node版本
推荐阅读
-
如何确定网站关键词?如何拓展关键词?
-
干货:网站快速拓展外链资源的几种方法
-
十、Spring boot 简单优雅的整合 Swagger2
-
使用Spring Boot和AspectJ实现方法跟踪基础结构
-
spring boot 一个项目启动多个实例
-
Mybatis整合spring(适合小白)
-
spring boot 2 集成JWT实现api接口认证
-
Spring Cloud系列-Zuul网关集成JWT身份验证
-
Jenkins + Docker + dockerfile-maven-plugin + Harbor CI/CD spring-boot项目的最轻量级配置
-
面试必问:Spring循环依赖的三种方式