关于数据库和缓存一致性问题

关于数据库和缓存一致性问题,网上的说法大都是先更新数据库,再删除缓存。可是如果是 :

1.线程A更新数据库
2.线程B查询从缓存中得到旧数据
3.线程A让缓存失效。

这样线程B不就是得到脏数据吗??请问有大佬帮忙解答一下吗?
#MySQL#
全部评论
先更新DB,在删除缓存,损失点一致性,虽然可能第一时间读不到最新的,但是逻辑没问题
点赞 回复 分享
发布于 2019-09-07 15:01
https://coolshell.cn/articles/17416.html
点赞 回复 分享
发布于 2019-09-07 15:02
老哥,我的理解:你的第3步错了,应该是让缓存失效。你说的那种情况是有可能发生的,A更新成功,B过来读缓存成功,获取老数据,之后A再让缓存失效;从此以后,后面的查询读的都是新数据了,因为缓存已经失效了,需要读数据库,然后把新的值设置到缓存里。。。所以你说的这种情况,只会影响那一次查询,只有一次,一次的概率很低很低,相对于先删缓存,在更新数据库造成的脏数据好太多了。 我的理解:1.先更新数据库,再删缓存最大的问题在于更新成功,没办法确保删缓存成功,因为没办法采用单机事务去保证这两个操作的原子性,所以可以采用一种不断重试的ACK机制,你可以自己写个重试机制,也可以使用市面上经常用的mq来保证,因为mq为了保证容错性,也实现了ack机制,步骤是可以用一个工具将mysql的binlog日志抓取出来,然后采用mq去确保删缓存一定会成功; 2.先更新数据库,再删缓存还有个弊端是:(1)A读数据,缓存失效,需要读数据库,(2)B更新数据库,更新成功,(3)B是缓存失效,(4)A将读出来的数据设置到缓存里,此种情况是会产生数据不一致的,但是这是极限状态更新数据库需要锁表,读数据库不需要,写的时间大于读的时间,所以此种情况很难发生,基于以上讨论,所以先更新数据库,再删缓存,相对于其他方法是比较理想的(或许未来会有更好的方法,但是目前这种方法所带来的的影响相对于其他的是较小的) 以上仅供参考,个人见解
点赞 回复 分享
发布于 2019-09-07 16:14
应该是先删缓存再更新据库吧。。。我认为流程是:先把缓存的数据删了,然后更新数据库,最后重新注入缓存
点赞 回复 分享
发布于 2019-09-07 14:56
感觉和事务的隔离性有关,四种隔离级别可以看下,如果隔离级别是脏读,那就有可能读到脏数据
点赞 回复 分享
发布于 2019-09-07 15:01
牺牲点一致性
点赞 回复 分享
发布于 2019-09-07 15:17
如果是针对秒杀这种一致性要求很高的场景呢?我看慕课上面就是直接用redis单线程访问控制,然后用消息队列来实现最终一致性。可是这样做性能应该很低下吧?
点赞 回复 分享
发布于 2019-09-07 15:20
弄个操作顺序的队列
点赞 回复 分享
发布于 2019-09-07 16:48
只有极高并发才可能出现楼主说的问题,上队列串行化可以解决
点赞 回复 分享
发布于 2019-09-08 09:31

相关推荐

点赞 评论 收藏
分享
点赞 评论 收藏
分享
点赞 20 评论
分享
牛客网
牛客企业服务