您可以推断,在您在此测试中使用的 MySQL 版本中,实现 并不真正符合可重复读取,就像您在其他版本中所说的那样问题,因为如果你已经完成了
事务 t2 从第 r1 行读取相同的数据
再次在第 4 步中,而不是
t2修改#2中读取的数据,并将数据提交给r1。
那么 t2 会读取 t1 在步骤 3 中保存的值。
所以你一开始没有重复阅读,所以这不是重复阅读丢失更新的情况。
ANSI SQL-92 根据现象定义隔离级别:脏
读取、不可重复读取和幻像。
而不是像你一开始想的那样when you said
现在,据我了解,RR 使用共享读锁和独占写入
锁
这是因为
ANSI SQL 隔离设计者寻求一个可以接受许多人的定义
不同的实现,而不仅仅是锁定。
事实上,READ_COMMITED implementation from SQL SERVER 就是一个例子。
如果 READ_COMMITTED_SNAPSHOT 设置为 OFF(默认),数据库
引擎使用共享锁来防止其他事务修改
当前事务正在运行读取操作时的行。 [...]
如果 READ_COMMITTED_SNAPSHOT 设置为 ON,则数据库引擎使用行
版本控制以呈现每个语句的事务一致
语句开始时存在的数据快照。
锁不用于保护数据不被其他人更新
交易。
丢失更新不是这种现象之一,但在A Critique of ANSI SQL Isolation Levels 中Argeman 在the other question 中指出,repeteable read 保证不会丢失更新:
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 or a1) and (c2 or a2) 任意顺序)