Mysql如何实现可重复读
首先对于mysql来说相信也并不陌生,mysql默认的事务的隔离级别是3,即可以实现可重复读,那mysql又是怎样实现可重复读的呢?下边进行简单的介绍这里就要提到了mvcc,即多版本并发控制首先先来看一个事务的执行图此时分别有四个事物及其执行顺序事务1,将名字更改为张三并提交事务2,将名字更改为张小三并提交事务3,将名字更改为张老三并提交事物4,进行两次查询,注意图中的查询时机在RR级别:sele
首先对于mysql来说相信也并不陌生,mysql默认的事务的隔离级别是3,即可以实现可重复读,那mysql又是怎样实现可重复读的呢?
下边进行简单的介绍
这里就要提到了mvcc,即多版本并发控制 首先先来看一个事务的执行图此时分别有四个事物及其执行顺序
- 事务1,将名字更改为张三并提交
- 事务2,将名字更改为张小三并提交
- 事务3,将名字更改为张老三并提交
- 事物4,进行两次查询,注意图中的查询时机
在RR级别:select1=张三 select2=张三
在rc级别下:select1=张三 select2=张小三
在rc级别下出现了不可重复读。
基于undo_log的版本链
readview是什么
readview是快照读sql执行时mvcc提取数据的依据
快照读就是最普通的select查询sql语句
当前读指执行下列语句进行数据读取的方式
insert、update、delete
select … for update select … lock in share mode
版本链数据访问规则:
- 判断当前事物id是否等于creator_trx_id?成立的话就说明就是自己的事物更改的,则可以访问
- 判断trx_id<min_trx_id? 成立就说明事务已经提交了,可以访问
- trx_id>min_trx_id?成立说明该事务是在readview生成以后才开启,不允许访问
- 判断min_trx_id<=trx_id<=max_trx_id,成立在m_ids数据中对比,不再当前活跃事务中的即代表数据已经提交了,即是可以访问的
我们先来分析事务4的第一次查询,此时它的readview是
- m_ids={2,3,4}
- min_trx_id=2
- max_trx_id=5
- creator_trx_id=4
再上图中的undo_log中进行寻找,即可读取到1号事务提交的数据,张三
可重复读(RR):仅在第一次执行快照读时生成readview,后续快照读复用(有例外)
RR级别下使用mvcc能避免幻读吗?能,但不完全能
连续多次快照,readview会产生复用,没有幻读问题
特例当两次快照之间存在当前读,readview会重新生成,导致产生幻读
更多推荐
所有评论(0)