//本文是对看到的文章进行的总结,文章原地址已经忘记了
一、先更新数据库,再更新缓存(Pass)
存在的问题:
//线程安全角度
- A更新了数据库
- B更新了数据库
- 因为网络的原因线程B先更新了缓存
- A更新了缓存
//业务场景角度
写多读少的场景:根本没去操作读数据,而缓存就被频繁的更新,浪费性能。
二、先删除缓存,再更新数据库
场景
- A进行写操作,删除缓存
- B发现缓存中没有,而直接读数据库,查到的旧值
- B将旧值写入缓存
- A将新值写入了数据库
存在的问题:A修改后的新值没有写入到缓存中。
处理方式:延时双删策略(先删除缓存,再更新数据库,然后休息ms,然后再删除缓存),最后一步可以做成异步(需要考虑失败的情况)。
三、先更新数据库,再删除缓存
步骤: 失效-命中-缓存
失效:应用程序先从cache取数据,没有得到,则从数据库中取数据,成功后,放到缓存中
命中:应用程序从cache中取数据,取到后返回
缓存:先把数据存到数据库中,成功后,再让缓存失效
场景:
- 请求A做读操作,B做写操作
- A做读操作的时候缓存刚好失效,得到一个旧值
- 请求B将新值写入数据库
- 请求B删除缓存
- 请求A将查到的旧值写入缓存
//这种场景下会发生脏数据,但是发生的概率很低。发生的先天条件是写的步骤比读更快,才有可能导致4/5问题的发生。
处理的方式:延时删除保证读完成后再进行删。
需要考虑(当出现写入数据库成功,但是删缓存失败了的异常处理),可以采用消息队列来处理