策略1. 先更新缓存,再更新数据库
策略2. 先更新数据库,再更新缓存
策略3. 先删除缓存,再更新数据库
策略4. 先更新数据库,再删除缓存(推荐)

先更新缓存,再更新数据库

应该没人用吧

如果更新缓存成功而更新数据库失败就会造成缓存脏数据

先更新数据库,再更新缓存

此方法照样不可取

如果线程A先更新了数据库,但由于网络原因还没更新缓存
这时线程B更新了数据库并更新了缓存,然后A才更新完缓存
导致B对缓存的更新丢失,就像事务丢失那样
image.png

先删除缓存,再更新数据库

这种策略避免可以缓存丢失,但高并发情况依然会有不一致的情况

线程A准备做写操作,先删除了缓存
线程B做读操作时发现缓存没有命中,然后从数据库中读取,并将旧值写入缓存
这时线程A才将数据库修改完成
于是造成数据库是新值,缓存是旧值,数据不一致现象产生

image.png

解决方案 :延迟双删

先删除缓存再读取数据库,在完成数据库更新之后稍作延迟再删一次缓存

延迟时间 > 一次读操作时间

先更新数据库,再删除缓存(推荐)

依然会有数据不一致现象发生的可能
线程A读取数据库并准备写入缓存时,线程B更新数据库并写入缓存
线程B操作结束时A才把之前读取的旧值写入缓存,造成数据不一致情况

image.png
但这种情况发生概率较低,因为读操作通常比写操作耗时短

解决方案仍然是延迟双删

延迟双删可能发生的问题:删除缓存失败

不断的循环删除

解决方案:队列

将删除失败的key放入队列,重复尝试删除直到成功

**