mysqlMVCC+间隙锁解决幻读理解
mysql的隔离级别?
读未提交 -》读提交 -》可重复读 -》串⾏化
InnoDB默认级别为可重复读,可重复读会产⽣问题就是幻读。
什么是幻读?
不可重复读侧重于update这种操作,同⼀条数据前后读起来不⼀样的情况,
幻读侧重于insert delete这种操作,前后两次select 数据的数量会发⽣变化计算机女生就业方向
举个例⼦:
事务A 第⼀步 select * 第⼆步 update 所有字段第三步再次select *
事务B 执⾏了insert ⼀条语句
幻读第⼀种情况:当事务A 刚执⾏完第⼀步,事务B insert⼀条,导致事务A update执⾏完,再次select发现多了⼀条数据
幻读第⼆种情况:当事务A 刚执⾏完第⼆步,事务B insert⼀条,导致事务A 再次select 发现有⼀条数据没有update字段
InnoDB如何解决幻读的?
Mvcc+⾏锁+间隙锁
什么是间隙锁?
正常等值条件并且值存在的情况下加的是⾏锁
如果等值条件值不存在的情况下加的是间隙锁,或者范围查询,加的也是间隙锁
举个例⼦:
根据主键id,不只是有五个⾏锁,还会有六个间隙锁,左开右闭原则,(-∞,5](5,10](10,15](15,20](20,25](25,+supernum]例如 select * from table where id = 10 for update; 等值条件,id是存在的,加⾏锁就可以了
select * from table where id = 7 for update; 等值条件,id不存在,加(5,10] 间隙锁,这范围间不允许插⼊数据,直到这个事务提交完成释放锁
mysql怎么读英语malloc的函数select * from table where id > 24; 范围条件,加间隙锁
通过⾏锁+间隙锁的机制保证了事务A select之后,其他事务相应的insert操作会阻塞
什么是undolog?
undolog存放不同事务版本下的不同数据,
⽤于 1.历史恢复通过undolog恢复之前版本的数据 2. 读⽼版本根据条件读旧版本的数据
每次数据变更都会产⽣undolog记录,undolog记录分为 insert undo_log 和 update undo_log
insert操作属于insert undo_log,只针对当前事务,在insert操作后产⽣undo_log记录,在事务提交后删除undo_log记录,说⽩了就是给当前事务⾃⼰看的.
update 和 delete操作属于update undo_log,会根据隔离级别不同事务版本的数据可见性不同
什么是readView?
快照存放了当前活跃的⼀些事务版本号,以及上⼀个版本的地址. ⽤来做可见性判断
readview根据⽣成时间不同,产⽣了RC,RR两种可见性
c教程论坛c十十编程教学RC:每条select创建⼀个新的readview ,所以导致读提交读到的都是最新提交的!
RR:事务开始的时候创建⼀个readview, ⼀直到事务结束都⽤的这个readview,也就避免了不可重复读
当前读与快照读
单条普通的select语句属于快照读
select for update , insert, update, delete 属于当前读
快照读由mvcc+undolog实现
当前读由⾏锁+间隙锁实现
什么是MVCC?
多版本并发控制(Multi-Version Concurrency Control, MVCC)
仅在读提交和可重复读两种隔离级别下⽣效
洛必达法则每⾏记录字段都保存有⼀个最近变更事务Id ⼀个最新删除的事务Id
haskell stack事务读数据的原则就是:读版本号⼩于等于当前版本的数据(意思就是读不到在当前事务之后修改的数据避免了不可重复读)
读删除事务版本号⼤于等于当前版本的数据(意思就是如果这条数据在之后的事务⾥删了,当前事务也不能再读了) InnoDB实现mvcc 是通过 readview+undolog 来实现
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论