你可以推断出在版本中您在本次测试中使用的 MySQL 的实现并不真正符合可重复读取,就像您在其他问题中所说的那样,因为如果您已经完成了
事务 t2 从 r1 行读取相同的数据
再次在步骤 4 中代替
t2 修改 #2 中读取的数据并将数据提交到 r1。
那么 t2 就会读取 t1 在步骤 3 中保存的值。
所以你一开始就没有可重复读,所以不属于可重复读丢失更新的情况。
ANSI SQL-92 根据现象定义隔离级别:脏
读取、不可重复读取和幻像。
而不是像你一开始想象的那样是锁当你说 https://stackoverflow.com/q/10040785/3517383
现在,据我了解,RR使用共享读锁和独占写
锁
这是因为
ANSI SQL 隔离设计者寻求一个可以容纳许多人的定义
不同的实现,而不仅仅是锁定。
事实上,这方面的一个例子是SQL SERVER 的 READ_COMMITED 实现 https://msdn.microsoft.com/es-es/library/ms173763(v=sql.120).aspx.
如果 READ_COMMITTED_SNAPSHOT 设置为 OFF(默认值),则数据库
引擎使用共享锁防止其他事务修改
当前事务正在运行读取操作时的行。 [...]
如果 READ_COMMITTED_SNAPSHOT 设置为 ON,则数据库引擎使用行
版本控制以呈现事务上一致的每个语句
语句开始时存在的数据快照。锁不用于保护数据不被其他人更新
交易.
丢失的更新不是这种现象之一,而是在对 ANSI SQL 隔离级别的批评 http://www.cs.umb.edu/%7Eponeil/iso.pdf阿格曼指出另一个问题 https://stackoverflow.com/questions/10040785/mysql-repeatable-read-and-lost-update-phantom-reads解释了可重复读取保证不会丢失更新:
P1 = 不可重复读取
P4 = 丢失更新
P2 的宽松解释(指定可能导致
到异常)是
P2: r1[x]...w2[x]...((c1 or a1) and (c2 or a2) in any order)
P2(指定实际异常)的严格解释(称为 A1)是
A2: r1[x]...w2[x]...c2...r1[x]...c1
虽然丢失更新的解释是
P4: r1[x]...w2[x]...w1[x]...c1
您提出的案例采用以下形式:
A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2
乍一看,这似乎是一种没有不可重复读取的情况,实际上 t1 在整个事务中始终会读取相同的 x 值。
但如果我们关注 t2 并反转数字,我们可以看到这显然是不可重复读取的情况。
A4: r1[x]...r2[x]...w1[x]...c1...w2[x]...c2
A4: r1[x]...w2[x]...c2...w1[x]...c1(数字反转以提高可读性)
P2: r1[x]...w2[x]...((c1 或 a1) 和 (c2或a2) 以任何顺序)