MySQL事务+MVCC(精简版,包教包废)
加油加油,冲刺秋招
事务概念
一组操作的最小单元,所有操作要么同时成功,要么同时失败
事务四大特性ACID及实现原理
原子性(Atomicity)
所有操作要么同时成功,要么同时失败。事务不可再分
原子性通过undolog实现,事务回滚通过undolog进行
一致性(Consistency)
事务执行前后数据总状态一致
一致性通过原子性,持久性,隔离性一起实现
持久性(Isolation)
事务对数据库的改变是永久的,哪怕数据库宕机也不会发生改变
持久性通过redolog实现
隔离性(Durability)
事务之间不会相互影响
隔离性通过MVCC实现
具体讲讲四大特性是怎么实现的?
并发事务带来的问题
脏读 :事务A读到事务B未提交的数据
脏写 :事务B覆盖了事务A先写入的数据,最后一个更新的覆盖了之前更新的数据
不可重复读 :事务A相同的查询语句前后执行的结果不同
幻读 : 事务A两次查询前后读取的数据量不同
Mysql的隔离级别
读未提交:顾名思义,解决不了并发事务带来的问题
读已提交:事务A只能读到其他事务已提交的数据,通过MVCC实现,解决脏读脏写的问题
可重复读:在事务执行过程中,数据是一致性的
可串行化:会对记录加上读写锁,解决所有事务的并发问题,所以性能自然差一些
MVCC
mvcc基础概念
Mvcc:多版本并发控制器,解决事务读写冲突的问题,对事务进行隔离。通过ReadView+undolog指针实现
ReadView:数据快照,包含四大元素。最小事务id,最大事务id,活跃事务id列表
ReadView的读取规则(结合事务的隔离性就很好理解了):
1比最小事务id小,说明在此事务开始前就提交了,肯定能读到
2比最大事务id大,说明在此事务之后才开启,一定不读
3在活跃id列表里面,说明事务还未提交,不读
4比最小事务id大,比最大事务id小,不在活跃id列表里面,说明事务提交了,可以读
5当前事务id,自己的肯定读
快照读:普通select语句,读取数据某一时间点的版本,读取的是
当前读:select for update语句,读取数据当前最新的版本,可以看到其他事务对数据的改变
MVCC怎么实现读已提交和可重复读的?
读已提交:每次读取的是最新的数据,每次读取都会生成一个ReadView
可重复读:事务开启时才会生成数据快照,之后事务执行期间都使用这个快照
读已提交和可重复读的本质区别在于ReadView的生成时间不同
MVCC能解决幻读吗?(评论区回答)
MVCC在可重复读级别下可以解决部分幻读问题
针对快照读:
针对当前读