赞
踩
当前读: 就是读取当前最新的数据,并且对读取的数据加锁,阻止其他事务同时修改相同的记录,避免出现安全问题。
使用场景:update、delete、insert
select … lock in share mode (主动加共享锁)
select … for update (主动加排他锁)
可重复读隔离级别下当前读是如何避免幻读的?
通过 next-key lock(记录锁+间隙锁)方式解决了幻读。
快照读: 是基于mvcc+undolog实现的,读取mvcc版本链上的某个版本,很可能是历史版本,不用枷锁,不加锁的简单的SELECT 都属于快照读,
InnoDB在隔离级别读已提交级别和可重复读级别上使用
快照读不会在访问的表上加任何锁,其他会话可以同时修改表上的数据。
读已提交级别下,每次select都会生成一个快照。
可重复读级别下,开启事务之后第一个select才会生成快照,而不是事务一开始就生成快照。
可重复读隔离级别下快照读是如何避免幻读的 :可重复读隔离级是由 MVCC(多版本并发控制)实现的,实现的方式是启动事务后,在执行第一个查询语句后,会创建一个 Read View,后续的查询语句利用这个 Read View,通过这个 Read View 就可以在 undo log 版本链找到事务开始时的数据,所以事务过程中每次查询的数据都是一样的,即使中途有其他事务插入了新纪录,是查询不出来这条数据的,所以就很好了避免幻读问题。
MVCC是什么? 多版本事务并发控制
多版本指 版本链 并发场景下,用版本链控制事务读取的是版本链上的那个结果
版本链是什么?
undolog版本链是指 一行数据被多个事务修改后,每一次事务修改后,mysql会保留修改之前的数据到undo回滚日志,并且用trx_id(事务id)和roll_pointer回滚指针两个隐藏字段把这些undolog串联起来形成一个历史数据版本链
read-view机制(事务维度)
read-view有4个属性:
m_ids当前活跃事务列表, mix_trx_id m_ids里最小的值 ,mix_trx_id m_ids里最小的值
creator_trx_id当前事务id,每开启一个新的事务,就会生成一个read_view,creator_trx_id就是这个事务的id
实现原理是:
1. 按顺序判断比行数据的最新undolog事务id 比 mix_trx_id 一定读,比mix_trx_id 还小,说明产生这条undolog事务在readview生成的时候就已经提交了。
2.如果行数据的最新事务undoolog事务id和当前事务id相等,说明时当前事务修改的数据,一定可读
3. 如果行数据的最新undolog事务id在当前活跃事务id列表内,那也一定读不到,因为活跃事务id列表都是readview在生成的一瞬间还没提交的事务,没提交的当然不能读
如果最终判断行数据的undolog事务id读取不到数据,就会根据版本链继续往前一个节点,获取到事务id之后重新对比,直到找到一个符合规则的数据
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。