mvcc

mysql table t

id(primary_k)k
11

事务A,B,C的执行流程  (RR隔离级别下)

事务A事务B事务C
start transaction with consistent snapshot;  
 start transaction with consistent snapshot; 
  update t set k=k+1 where id=1;
 

update t set k=k+1 where id=1;

select k from t where id=1;

 

select k from t where id=1;

commit;

  
 commit; 

start transaction with consistent snapshot;命令可以立即启动一个事务;否则 begin/start transaction命令并不是事务的起点,而是执行到他们之后的第一个操作innodb表的语句,事务才会真正启动。

上述表格中,事务C没有显示的使用begin/commit,说明 update本身就是一个事务,语句执行完后自动提交;

上述事务执行结果,B查询到的k是3,而事务A查到的k是1

原因:

 

一个数据版本,对于一个事务视图来说,除了自己的更新总是可见之后,有以下3种情况:

1.版本未提交,不可见;

2.版本已提交,但是是在视图创建后提交的,不可见;

3.版本已提交,但是是在视图创建前提交的,可见。

基于以上,分析事务A的查询结果:

事务A的查询语句的视图数组在事务A启动的时候生成的,此时:

(1,3)还没提交(事务B执行结果),属于情况1   

(1,2)虽然提交了(事务C执行结果),但是是在视图数组创建之后提交的,属于情况2,不可见。

(1,1)是在视图数组创建之前提交的,可见。

再来看事务B,根据一致性读,(1.2)是在事务B的视图创建之后提交的,应该不可见,可为啥B能读出来呢?

原因就在于select之前的update语句。 事务根据数据的时候,只能用当前读。如果没有update,那读出来的数据就是(1.1)而不是(1,2)了。

综上:可重复度的核心就是一致性读。而事务根据数据的时候,只能用当前读。如果当前的记录的行锁被其他事务占用(即事务未提交),就需要进入锁等待。

好,以上是可重复读隔离级别下的执行结果。

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值