redis只管存不管删除 让失效时间删除的问题
- 一:背景介绍
- 二:思路&方案
- 三:代码模拟
- 1.错误示范
- 通过班级id查询课程名称
- 执行结果
- 通过班级id修改课程名称(并没有删除对应缓存)
- 执行结果
- 2.正确示范
- 在错误示范的更新接口上添加删除缓存的代码
- 四:总结
- 五:升华
一:背景介绍
本篇博客是对项目开发中出现的redis只管存不管删除 让失效时间删除的问题进行的总结和改进。目的是将经历转变为自己的经验。通过博客的方式分享给大家,大家一起共同进步和提高。
代码逻辑
- 通过redis查询该课程下所有班级的信息
- 如果没有从redis中查询到数据就从数据库中查询并存入到redis中一份
存在的问题
3. 并没有在更新课程下班级数据的时候删除缓存,会导致如果我更新了该课程下的班级数据,会导致缓存中的数据与数据中的数据不一致,当我再次查询数据的时候,如果我的key键没有过期会直接从redis中查询数据,但是查询的数据是没有更新之前的数据。如果我key键正好过期了才会从数据库中查询最新的数据,并更新到缓存中。
二:思路&方案
保证缓存数据与数据库中数据同步的方案。
- 查询的时候如果缓存存在则从缓存中获取,如果缓存不存在则从数据库中获取数据,并将获取到的数据存储在缓存中。
- 更新数据的时候删除缓存。
三:代码模拟
通过java maven项目模拟redis只管存不管删除 让失效时间删除的问题 进行错误示范和正确示范
代码环境:java maven项目、mysql,redis
pom.xml文件
<dependencies>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>compile</scope>
</dependency>
</dependencies>
1.错误示范
通过班级id查询课程名称
package org.example.controller;
import org.example.dao.UserInfoDao;
import org.example.entity.CourseConfiguration;
import redis.clients.jedis.Jedis;
/**
* @author : [WangWei]
* @version : [v1.0]
* @className : UserInfoController
* @description : [描述说明该类的功能]
* @createTime : [2022/11/30 11:43]
* @updateUser : [WangWei]
* @updateTime : [2022/11/30 11:43]
* @updateRemark : [描述说明本次修改内容]
*/
public class SelectCourseNameByClassId {
/*
* @description:通过班级id查询课程名称
* @author: wangwei
* @date: 2023/3/4 14:24
* @param: [args]
* @return: void
**/
public static void main(String[] args) {
//构造jedis,连接redis 并设置超时时间为100秒,在jedis的默认构造方法中,超时的时间一般被默认设置为2000毫秒,也就是2秒。
Jedis jedis=new Jedis("ip",端口号,100000);
jedis.auth("密码");
CourseConfiguration courseConfiguration=null;
//查询redis
String courseName = jedis.get("WangWei:ClassId");
if(courseName==""||courseName==null){
//从数据库中查询
UserInfoDao userInfoDao=new UserInfoDao();
courseConfiguration = userInfoDao.selectCourseNameByClassId(55801751);
//存入redis 并设置过期时间60秒
jedis.set("WangWei:ClassId",courseConfiguration.getCourse_name());
jedis.expire("WangWei:ClassId",60);
System.out.println(courseConfiguration.getCourse_name());
}else {
System.out.println(courseName);
}
}
}
执行结果
通过班级id修改课程名称(并没有删除对应缓存)
package org.example.controller;
import org.example.dao.UserInfoDao;
import org.example.entity.CourseConfiguration;
import org.example.utils.RedisConfig;
import redis.clients.jedis.Jedis;
/**
* @author : [WangWei]
* @version : [v1.0]
* @className : UpdateCourseNameByClassId
* @description : [描述说明该类的功能]
* @createTime : [2023/3/4 14:26]
* @updateUser : [WangWei]
* @updateTime : [2023/3/4 14:26]
* @updateRemark : [描述说明本次修改内容]
*/
public class UpdateCourseNameByClassId {
/*
* @description:通过通过班级id修改班级名称
* @author: wangwei
* @date: 2023/3/4 14:27
* @param: [args]
* @return: void
**/
public static void main(String[] args) {
//修改班级名称
UserInfoDao userInfoDao=new UserInfoDao();
userInfoDao.updateCourseNameByClassId(55801751,"ARPro计算机思维课程-开发班课");
// //连接redis
// Jedis jedis=new Jedis("82.157.199.3",6379,100000);
// jedis.auth("000415");
// //删除key键
// jedis.del("WangWei:ClassId");
System.out.println("修改成功!");
}
}
执行结果
这个时候我们再执行 通过班级id查询课程名称的接口由于WangWei:ClassId这个key键还没有过期,会发现查询的还是之前没有修改的课程名称。数据出现不一致。
当key键WangWei:ClassId过期时由于查询的是数据库中的数据,所以数据是一致的。
2.正确示范
- 查询的时候如果缓存存在则从缓存中获取,如果缓存不存在则从数据库中获取数据,并将获取到的数据存储在缓存中。
- 更新数据的时候删除缓存。
在错误示范的更新接口上添加删除缓存的代码
package org.example.controller;
import org.example.dao.UserInfoDao;
import redis.clients.jedis.Jedis;
/**
* @author : [WangWei]
* @version : [v1.0]
* @className : UpdateCourseNameByClassId
* @description : [描述说明该类的功能]
* @createTime : [2023/3/4 14:26]
* @updateUser : [WangWei]
* @updateTime : [2023/3/4 14:26]
* @updateRemark : [描述说明本次修改内容]
*/
public class UpdateCourseNameByClassId {
/*
* @description:通过通过班级id修改班级名称
* @author: wangwei
* @date: 2023/3/4 14:27
* @param: [args]
* @return: void
**/
public static void main(String[] args) {
//修改班级名称
UserInfoDao userInfoDao=new UserInfoDao();
userInfoDao.updateCourseNameByClassId(55801751,"ARPro计算机思维课程-开发班课");
//连接redis
Jedis jedis=new Jedis("82.157.199.3",6379,100000);
jedis.auth("000415");
//删除key键
jedis.del("WangWei:ClassId");
System.out.println("修改成功!");
}
}
通过以上的缓存同步测试,就可以保证缓存中的数据与实际数据库中的数据保持一致。
四:总结
1.出现这次redis只管存不管删除的问题,在于对于redis在实际项目中的使用不够熟悉了解,不清楚缓存同步的策略。推荐需要对redis参照官网进行系统性的学习,以及与其他高人进行讨论交流。
2.其实对于此次问题,如果没有遇到这个案例,自己也很有可能会同样的获取,由于自己本身对于redis的使用没有涉及到,以及考虑到redis缓存同步。
五:升华
通过这次的案例分析,对于认知上需要提升的点,自己也有了针对性提升对于知识认知上的方式方法。如思维导图,三篇读数法,参照官网对例如redis进行快速浏览,通过思维导图宏观了解,提升认知,不怕不知道就怕不知道。