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

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

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

并发事务的数据更新

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

在上图中,流程如下:

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

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

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

Alice提交了她的事务;

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

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

数据库如何防止这种现象

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

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

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

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

  • 发表于:
  • 原文链接https://kuaibao.qq.com/s/20180719B0CD5K00?refer=cp_1026
  • 腾讯「云+社区」是腾讯内容开放平台帐号(企鹅号)传播渠道之一,根据《腾讯内容开放平台服务协议》转载发布内容。
  • 如有侵权,请联系 yunjia_community@tencent.com 删除。

扫码关注云+社区

领取腾讯云代金券