mysql 一致性非锁定读有些迷惑。

mvcc会读到旧版本数据,但读到旧版本数据不一定就是错误。定义错误的标准就是看是不是可串行化。可串行化,简单的说就是好像事务是一个接着一个串行的执行一样。一致非锁定读(snapshot),并不一定是不可串行化的。

例如,调度H1,
H1: R1(Y0, 30) R2(X0, 50) W2(X2, 70) C2 R1(X0, 50) C1
(说明: R1(X0, 50)代表事务T1读取X被事务T0写入的旧版本50;W2(X2, 70)代表事务T2对X写入新版本70;C1代表事务T1提交。以此类推 )
因为H1和调度H\u0026#39;
H\u0026#39;=R1(Y0, 30) R1(X0, 50) C1 R2(X0, 50) W2(X2, 70) C2
有相同的『效果』,H\u0026#39;是一个串行的调度,H1是一个与之Conflict Equivalence的等价调度,H1是一个可串行化的调度。虽然事务T1读了X的旧版本,但事务是『正确』的。
调度H2,H2: R1(X0, 70) R2(X0, 70) R1(Y0, 80) R2(Y0, 80) W1(X 1, ?30) C1 W2(Y2, ?20) C2因为无法找到一个与之Conflict Equivalence的等价调度,所以H2是不可串行化的。类似这种不可串行化的异常被称为write skew。

实际应用场景中,对数据库的访问都是有特定的access pattern的,特定的access pattern不会在一致非锁定读(snapshot)隔离下发生错误。比如常用作OLTP的benchmark TPCC,就不会发生类似H2的错误。另为许多隔离性要求不高的场景下,即使发生一些错误,也可以接受。

MySQL怎么实现隔离级别的
MySQL 是如何实现四大隔离级别的?
Write Skew在MySQL上的例子
【mysql 一致性非锁定读有些迷惑。】 关于mysql的InnoDB多版本并发控制(MVCC)与事务隔离级别的疑问?
MySQL还有一个比较怪异的地方,就是并发的写写冲突不回滚,这个也会导致异常
请问 Mysql/Innodb 的 RR 模式下哪种情况下需要手动加锁啊?


    推荐阅读