什么是缓存
在业务开发的每个流程都能够构建缓存

缓存的一些优点与缺点
这里的缺点其实都是为了保证一致性

首先第一个添加商品缓存
下面这个getById实际上是IService(Mybatis plus)提供的一个函数,直接替我们实现了mapper层的功能

添加缓存完整流程

缓存穿透



缓存雪崩
第一个是大量key失效,后面三个都是redis宕机的操作,其中后两个都是微服务部分学的

缓存击穿



互斥锁实现流程

这里不是之前学的那种简单的lock加锁,因为以前的是请求不到锁就等待资源释放,但是现在要实现一个请求不到就等一会再请求,因此需要自己进行实现。这里实际上是使用功能redis的string类型中的setnx命令来实现的。为什么它能够实现呢?这是因为setnx有一个功能,就是如果没有值就修改,有值就不修改。如下图,只有第一个人能修改,后面都不能修改。具体就是setnx设置锁,实现完成以后就删除来释放锁。同时为了防止设置锁以后出现一些故障无法查询数据库导致死锁,因此可以给setnx设置有效期


java中的setnx命令

设置锁
后面不是直接返回的原因是有时候可能有空指针,因此使用工具类实现。



逻辑过期



下面这一步需要注意,因为上面我们创建了一个RedisData类型的变量,但是你能发现其实其中的data实际上是一个object类型的变量,如果直接进行类型转换,getData无法将其转换成Shop对象,因为实际上存储的时候是一个object而不是shop,但是这里的类型还必须设置为object,因为需要保证代码的扩展性。此时就可以转换为下面的JsonObject类型来存储就可以了



## 创建线程池

独立线程的具体操作

封装redis工具类

两个set函数:

下面的是解决缓存穿透问题的。下面这一段实际上使用了泛型与函数式编程来实现对不同类型的通用操作


方法中调用的时候可以极大地简化

后面的缓存击穿封装也是类似的


调用也是很简单的
