你真的明白什么是幻读吗?

导读:幻读是指当事务不是独立执行时发生的一种现象。很多程序员虽然工作多年,但是对幻读依然了解的不够。本文作者分析了幻读出现的一般原因,并对数据库的处理策略做了总结。


数据库事务由4ACID定义的。隔离级别(ACID中的I)是允许用户指定数据完整的折中方案。隔离级别越弱,产⽣问题的可能性越多。这里我们讲一下幻读问题。

并发事务的数据更新


如果⼀个事务基于给定的数据列集合做业务决策,而没有范围锁,一个并发的事务可能会导致新增一⾏记录,引发这种特殊的情况。

640?wx_fmt=png

在上图中,流程如下:

  1. Alice和Bob开启了数据库的两个事务;

  2. Bob读取post_comment表中所有post_id为1的数据;

  3. Alice增加了一条post_id为1的数据;

  4. Alice提交了她的事务;

  5. 如果Bob重复读取post_id为1的数据,他将发现不一样的结果集;

如果当前事务基于第一次返回的结果做了业务决策,那么就会产生问题。

数据库如何防止这种现象


SQL标准这么定义幻读,在两个连续的查找之间一个并发的修改事务修改了查询的数据集,导致这两个查询返回了不同的结果。

尽管提供读一致性是可序列化的强制要求,但是还不够。例如,一个买家可能购买产品⽽不知道在他提交订单之后的瞬间,商品有更低的报价。

两阶段加锁(2PL-based)序列化隔离使用谓词锁,通过访问MVCC数据库引擎返回的快照,来防止幻读。

尽管如此,并发的事务仍然有可能修改被读取过的数据。甚⾄MVCC数据库引擎实现了事务调度,不同的请求通过两阶段加锁实现依然可能返回不同的结果。例如,第2个事务添加了一条记录,不在第1个事务的读取记录中。在这种特殊的应⽤场景中,很多MVCC数据库引擎将不会回滚前⾯的事务。

本文作者VLADMIHALCEA,由邓启明翻译,转载本文请注明出处,技术原创及架构实践文章,欢迎通过公众号菜单「联系我们」进行投稿。

推荐阅读

高可用架构

改变互联网的构建方式

640?wx_fmt=jpeg

长按二维码 关注「高可用架构」公众号

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值