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用于移除掉符合条件的实体
具体的代码因为还缺少同步、测试所以暂时不上传
分享到:
相关推荐
spring.cache.type=redis spring.datasource.username=root spring.datasource.password=123456 spring.datasource.url=jdbc:mysql://127.0.0.1:3306/shiro_action?useSSL=false&characterEncoding=UTF8 启动项目 ...
- 使用最新技术栈,社区资源丰富,基于Java 21(Core Module Support 17-21)、Spring Boot 3.2。 (Support Virtual Threads/fibre/loom) - 基于注解的动态查询(Specification),可根据需要扩充查询注解。 - 支持...
- Spring Cache + Redis: 实现缓存机制。 - Spring Task: 定时任务支持。 - JWT: 用户认证。 - Websocket: 实现实时通信。 - Apache POI: 文件处理。 - 阿里云OSS: 文件存储。 - Swagger: API文档生成。 - ...
2. 缓存策略:利用Spring Cache或Redis实现缓存,减少数据库访问,提高系统性能。 3. 安全防护:使用Spring Security或OAuth2进行权限控制,防止XSS、CSRF等攻击。 总结,本项目通过SpringBoot与Vue.js的深度融合...
cache: false # 关闭缓存 prefix: classpath:/views/ # 添加路径前缀 ``` 编写 Thymeleaf 模板 编写 Thymeleaf 模板和书写 HTML5 页面没有什么不同,最大的转变就是使用拓展属性(th:xx)去跟服务端进行数据交互...