RR级别下update操作的是快照读还是当前读?

我们知道在RR级别下,重复的select操作,读取的值都会是一致的。即便在两次select操作的中间,有一个事务B修改了值,但是在事务A中select读取的值还是一致的。

那么如果是update操作呢?之前在网上看到一篇博客说RR级别下,CAS操作是没有意义的。因为version值在一个事务中都是一致不变的。于是我有了疑惑打算自己来验证一下。

验证想法

RR级别下update操作的是快照读还是当前读?

准备数据

准备了以下简单的表数据结构。

sidnamesexversion
1zhangsan00
2lisi10

验证思路

  • 通过version值做CAS版本,修改sex值。
  • A事务先执行,通过sleep 5秒延迟最后的update操作。
  • B事务后执行,通过sleep 1秒使得它虽然事务id更大,但比A事务更早执行完成。
  • 查看A事务通过version字段CAS操作能否修改成功sex值。
  • 如果能修改成功即update语句where条件定位的是快照读,反之则定位的是当前读。

事务脚本

事务A

事务A先执行,事务id小

begin;

SELECT version from student where sid = 1;   
// 当前获取的version为0
SELECT SLEEP(5);

SELECT version from student where sid = 1;
// 此时获取的version依然为0
update student set sex = 1 , version = version +1 where sid = 1 and version = 0;
// 修改行数为0,修改操作失败,说明version已经不是0了,
commit;
事务B

事务B后执行,事务id大

begin;

SELECT version from student where sid = 1;
// 当前获取的version为0
SELECT SLEEP(1);

SELECT version from student where sid = 1;
// 此时获取的version依然为0
update student set sex = 2 , version = version +1 where sid = 1 and version = 0;
// 修改成功,此时当前version为1  
commit;

验证结果

事务A的update操作失败,说明update中的where条件定位的记录是当前读而非快照读。


标题:RR级别下update操作的是快照读还是当前读?
作者:valarchie
地址:http://vc2x.com/articles/2020/04/08/1586333970679.html
技术讨论群:1398880
本文为博主原创文章,转载请附上原文出处链接。