给查询业务添加redis缓存和缓存更新策略

目录

一、添加redis缓存的主要逻辑

二、代码

三、结果

四、缓存更新策略

五、代码


一、添加redis缓存的主要逻辑

在未添加缓存时,前端向后端发起查询请求时,后端收到请求就直接查数据库,它的速度如下:

其实速度也不慢,那是因为我的数据库里面没有太多数据,所以查起来速度还是特别快的,但随着我们的数据库数据量逐渐增大,如果没有缓存的话,那查询速度会越来越慢。

添加redis缓存的逻辑也不难,总结下来也就是以下这几点:

1.后端查询时,先查redis缓存,redis缓存中有数据直接返回,没有数据再去查数据库

2.查数据库时,没有对应数据则向前端发出错误信息,有数据则向前端发送数据并将数据写入redis缓存中

流程图如下所示:

二、代码

java 复制代码
@Service
public class ShopServiceImpl extends ServiceImpl<ShopMapper, Shop> implements IShopService {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    /**
     * 根据id查询店铺信息
     * @param id
     * @return
     */
    @Override
    public Result queryById(Long id) {
        String key = RedisConstants.CACHE_SHOP_KEY + id;
        //1.从redis中查询商铺缓存信息
        String shopJson = stringRedisTemplate.opsForValue().get(key);
        //2、判断是否存在
        if (StrUtil.isNotBlank(shopJson)) {
            //3、存在,直接返回
            Shop shop = JSONUtil.toBean(shopJson, Shop.class);
            return Result.ok(shop);
        }
        //4、不存在,根据id查询数据库
        Shop shop = getById(id);
        //5、判断数据库中是否有数据
        if (shop == null) {
            //6、没有,返回错误
            return Result.fail("店铺不存在");
        }
        //7、有数据,返回,并将数据写入redis
        String jsonStr = JSONUtil.toJsonStr(shop);
        stringRedisTemplate.opsForValue().set(key,jsonStr);
        //8、返回结果
        return Result.ok(shop);
    }
}

三、结果

当第一次执行时,redis中是没有数据的,执行过后就会将对应数据写入redis中

下一次的查询时速度就会快上不少

如果数据库中的数据更多的话,效果会更加明显

四、缓存更新策略

既然我们已经对查询业务增加了缓存,那当数据库的数据和缓存数据不一样的时候,我们如何去解决它们之间的一致性问题呢?

其实解决方案十分简单:

当数据库的数据发生变更时,例如增加、删除、修改等操作,我们先去操作数据库再去删除缓存。

为什么选择删除缓存而不选择更新缓存呢?

如果选择更新缓存很可能会出现多次无效的写操作,比如:我更新了十次数据库之后才有一次查询操作,这时候缓存也是随之更新了十次。那如果我在他第一次更新数据库的时候就选择删除缓存,那么我就省去了这些更新缓存的无效写操作,性能上肯定是提高了不少。因此我们会选择删除缓存而不是更新缓存。

为什么要选择先操作数据库而不是先操作缓存呢?

因为数据库是基于磁盘的,缓存是基于内存的,操作数据库的耗时往往会比操作缓存的耗时大上不少。因此如果先删缓存再更新数据库,那就会出现在更新数据库的过程中(时间比较长)被其他查询缓存的操作乘虚而入,这时候缓存为空会从数据库中拿数据填入缓存,这时候就会出现数据不一致的问题。因此我们会选择先操作数据库再操作缓存。

因此我们还要给上面写的代码进行补全,在对数据进行修改的时候要进行以下的逻辑:

1.更新数据库

2.删除缓存

五、代码

java 复制代码
    @Override
    @Transactional
    public Result update(Shop shop) {
        Long id = shop.getId();
        if (id == null) {
            return Result.fail("店铺id不能为空");
        }
        //1.更新数据库
        updateById(shop);
        //2.删除缓存
        stringRedisTemplate.delete(RedisConstants.CACHE_SHOP_KEY + id);
        //3.返回结果
        return Result.ok();
    }
相关推荐
CaiGbro8 分钟前
IDEA自定义文件打开格式
java·git·intellij-idea
只是有点小怂12 分钟前
用魔方做存储器
缓存
JavaEdge.14 分钟前
ShardingSphere 如何完美驾驭分布式事务与 XA 协议?
java
T.O.P1120 分钟前
Redis 5 种基本数据类型详解
数据库·redis·缓存
红队it29 分钟前
【计算机毕设】无查重 基于python豆瓣电影评论舆情数据可视化系统(完整系统源码+数据库+开发笔记+详细部署教程)✅
数据库·笔记·python·算法·机器学习·信息可视化·数据分析
树下熊猫37 分钟前
企业案例:钉钉宜搭对接金蝶云星空
数据库·钉钉
我焦虑的编程日记41 分钟前
【蓝桥杯算法】Java的基础API
java·算法·排序算法
2401_857617621 小时前
基于Spring Boot的电子商务平台架构
spring boot·后端·架构
想当厨子的小章同学1 小时前
MySql 日期周处理方式
大数据·数据库·sql
心灵彼岸-诗和远方1 小时前
高效协作:前后端合作规范与应对策略优化
java·架构·devops