MySQL事务隔离级别和MVCC

MVCC 英文全称为Multi-Version Concurrency Control,翻译为中文即 多版本并发控制。实现非堵塞式并发访问。这个原理有点类似《Java里面的CAS实现原理》谁像谁说不定类比来学吧

  • 事务隔离级别
    脏写:一个事务修改了另一个未提交事务修改过的数据,也就是区修改别人未提交的部分当回滚时就修改不复存在了。
    脏读:一个事务读到了另一个未提交事务修改过的数据,同样的回滚时就读取到了一个不存在的数据,
    不可重复读:就是说一个事务没有提交的时候读取了另一个数据,读取之后这个数据被另外一个事务给修改了,当这个未提交的事务再次读取该数据时和之前的不一样了。这就发生了不可重复读,就是在同一事务读取多次的值不一样。
    幻读:和不可重复读类似,不过是两次读取的记录数量不一样,像幻影般突然的出现。
    SQL标准的隔离级别如下:
隔离级别名称脏读不可重复读幻读
READ UNCOMMITTED未提交读PossiblePossiblePossible
READ COMMITTED已提交读Not PossiblePossiblePossible
REPEATABLE READ可重复读Not PossibleNot PossiblePossible
SERIALIZABLE可串行化Not PossibleNot PossibleNot Possible

不出现脏写是因为,所有隔离级别都不允许出现脏写。

  • MySQL的隔离级别
    不同的数据库支持标准SQL的隔离级别是不一样的,MySQL四种隔离级别都支持,且MySQL的默认隔离级别为REPEATABLE READ,我们可以手动修改一下事务的隔离级别。而且MySQL在REPEATABLE READ隔离级别下,是可以禁止幻读问题的发生的。
    1、使用READ UNCOMMITTED隔离级别的事务,由于可以读到未提交事务修改过的记录,所以直接读取记录的最新版本就好了
    2、对于使用SERIALIZABLE隔离级别的事务来说,设计者规定使用加锁的方式来访问记录
    3、对于使用READ COMMITTED和REPEATABLE READ隔离级别的事务来说,都必须保证读到已经提交了的事务修改过的记录,也就是说假如另一个事务已经修改了记录但是尚未提交,是不能直接读取最新版本的记录的,核心问题就是:需要判断一下版本链中的哪个版本是当前事务可见的,
  • readview
    readview保存当前活跃的读写事务ID、当前活跃的最小事务ID、下一个即将生成的事务ID(通过生成事务的那个全局变量预测)、生成该readview的事务ID。有了这个readview,当要访问一个记录时先判断该记录的隐藏列中有一个事务ID,即修改该记录的事务ID,如果小于且不在活跃readview里的活跃列表,说明事务已经提交了就可以直接访问,如果还在活跃列表里就说明还在活跃不可以读取否则就脏读。如果大于就说明生成readview后才生成的事务是不可访问否则会出现不可重复读或幻读。当不可访问时即会获取隐藏列里的回滚指针找到undo日志然后继续对比直到可以访问或者版本链的结尾为止。《版本链是啥
  • RC和RR隔离级别的不同实现
    READ COMMITTED —— 每次读取数据前都生成一个ReadView
    也就是说事务里面有多次读取操作的话,每次读取都会生成一个ReadView快照,也就是说上一次读取的时的ReadView和本次读取的可能不一样,所以可能会读到不一样的版本也就是不可重复读或幻读
    REPEATABLE READ —— 在第一次读取数据时生成一个ReadView
    也就是说事务一旦开始,第一次查询和同一个事务中的第几次查询都是同一个ReadView,也就是版本定格快照在开启事务那个刻,以后每次读取到的版本都一样,也即是不会发生不可重复读或幻读
    脏读都不可能发生,因为这两种读取都在事务活跃的版本不可读的,也就是只能读取到已经提交的事务的版本。所以不可能脏读。

这个原理有点类似《Java里面的CAS实现原理》谁像谁说不定类比来学吧

  • 思考
    会发现MVCC好啊,不会堵塞,但是发现只是解决了读的问题,写入没法保证,怎么避免不会发生脏写呢,当然是通过锁的方式来了,修改一个记录前先锁住不给其他事务修改也就是不会发生脏写了。还有一个问题,当某个业务需要每次都要读到最新的值咋办这个MVCC读到的可能是旧版本,这需求当然也是通过锁来搞定了读写都锁就对了。还有就是明白一个是,常规的查询语气中不会加锁,除非显式的写加锁,常规不做其他声明的写语气中会加锁保证不会发生脏锁,,,,锁的详细内容
    转至《MySQL——锁机制简述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值