先操作哪个,主要问题不是其中一个执行失败的问题
1,先删除缓存,再更新数据库
存在主要问题不是更新数据库失败,导致读到老数据,
是并发情况下删除缓存后,立刻读库,此时库数据还没更新,读到了老数据,又写入了缓存,导致以后所有人读到都是缓存中错误数据
详细分析
出现不一致是因为并发情况,多线程操作导致
先删缓存,后更新库 A B两个线程
A删除缓存
B读旧数据库值
B更新旧值到缓存
A更新数据库
结果导致:缓存中是旧值,数据库是新值
2,先更新数据库,再删除缓存
存在主要问题是,更新数据库后,还没删除缓存,导致部分人读到了缓存中老数据,当缓存删除后,就可以从数据库读取正确数据,缓存也就正确,以后大部分人读到正确数据。
也会存在不一致问题
分场景
场景1,读多写少 读存在并发,写频率较低,出现不一致问题是 读 导致的
如下:可以忽略删除,只看原因:C线程读请求从数据库读到了旧值(为什么能读库,因为存在线程A删除了缓存),写入了缓存,B线程写请求,更新数据,删除缓存,处在A线程读库与写缓存之前。相当没有这个B写请求,实际有数据库正确,缓存不正确。
究其根本原因:B写操作:更新库,删除缓存两步,删除缓存太快了,C读请求中,写缓存太慢了,如果B删除缓存慢一点,在C写缓存之后,就算C写了旧值,B还是会把旧值删除,可以解决问问题,再分析一下,延时多久呢,会不会存在延时了,还会有类似C这样的请求,答案是不会,C读到旧值是在B写之前,可能存在类似C的,D,E,F请求,等B延时删除完成了,C肯定执行完成了。
再考虑延时双删,下文中说延时双删无用,还是没有考虑到延时到问题,删除缓存并没有慢一点。
场景2,写多,读多导致不一致问题
redis数据一致性之延时双删详解_xukaiqiang123的博客-CSDN博客_redis延时双删
分析一下,其实跟第一种差不多,更详细分析了,为什么延时双删能解决问题
其实延时双删,就是延时单删,更新数据库前删除缓存,意义不大。
再思考
先更新数据库,再删除缓存,缓存删除失败怎么办
参考如下:
四、异常情况
上面的讨论与对比都是在更新缓存
和更新数据库
这两步操作都成功的情况下叙述的。当然系统正常运行时的操作基本上都是成功的,那么如果两步操作有其中一步操作失败了呢?(以先操作数据库再操作缓存举例)
- 第一步失败:这种情况很简单,不会影响第二步操作,也不会影响数据一致性,直接抛异常出去就好了。
- 第二步失败:
- 将需要删除的缓存key发送到消息队列中(前提是知道删除缓存失败了)
- 另起终端消费队列消息,获得需要删除的缓存key
- 设置重试删除操作,超过最大重试次数(比如5次)后将消息转入死信队列并报警给运维人员