MVCC 是如何实现可重复读的?

2017-06-14 04:05:03 +08:00
 esolve

看了这篇文章 http://www.cnblogs.com/dongqingswt/p/3460440.html 里面说:

在查询时要符合以下两个条件的记录才能被事务查询出来:

  1. 删除版本号 大于 当前事务版本号,就是说删除操作是在当前事务启动之后做的。

  2. 创建版本号 小于或者等于 当前事务版本号 ,就是说记录创建是在事务中(等于的情况)或者事务启动之前。

我现在假设两个事务对一行数据操作,版本号分别为 4,5

该行数据的 create version 是 3

id value create-ver delete-ver 3 15 3

假如版本 5 的事务查询这行数据 value 为 15

假如 版本 4 的事务过程中更新这数据行,则变成

id value create-ver delete-ver 3 15 3 4 3 20 4

这个时候,版本 5 的事务再次查询 因为 delete-ver 为 4 的话,因为不满足删除版本号大于事务版本号,所以不能被查询到 这个时候好像是查到 value 为 20? ( delete-ver 为空,所以不需要满足删除版本号 大于 当前事务版本号?)

这样哪里体现了可重复读啊?

BTW: 好像用了 MVCC,update 或者 delete 的时候,老数据行都不被删除,这样数据库岂不是冗余太多?

2800 次点击
所在节点    问与答
8 条回复
esolve
2017-06-14 04:07:19 +08:00
上面的怎么变成一行了,再试试

----------------------------------------------------------

我现在假设两个事务对一行数据操作,版本号分别为 4,5

该行数据的 create version 是 3

id value create-ver delete-ver

3 15 3

假如版本 5 的事务查询这行数据 value 为 15

假如 版本 4 的事务过程中更新这数据行,则变成

id value create-ver delete-ver

3 15 3 4

3 20 4

这个时候,版本 5 的事务再次查询 因为 delete-ver 为 4 的话,因为不满足删除版本号大于事务版本号,所以不能被查询到 这个时候好像是查到 value 为 20? ( delete-ver 为空,所以不需要满足删除版本号 大于 当前事务版本号?)

这样哪里体现了可重复读啊?
miaoever
2017-06-14 09:04:00 +08:00
MySQL MVCC 在 Read repeatable 下,每个事务开始的时候会 “建立”一个 snapshot,事务中的读写都会在这个 snapshot 上执行。

https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html
mortonnex
2017-06-14 09:24:45 +08:00
乐观锁
esolve
2017-06-14 12:24:30 +08:00
@mortonnex。。。。。你说的真简便。。
esolve
2017-06-14 12:25:01 +08:00
@miaoever 我上面的例子我的错误在哪里?
ihuotui
2017-06-14 12:28:13 +08:00
楼主把 mvcc 和乐观锁两个概念混在一起了。乐观锁也不是这样用。为什么要删除
esolve
2017-06-14 19:36:45 +08:00
@ihuotui 我是根据那篇文章分析的啊
ihuotui
2017-06-14 21:37:32 +08:00
@esolve 不要乱看不知名的文章,描述不清还有可能误导,最好看官方文档即使自己翻译。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/368224

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX