事务隔离级别实现原理和锁-InnoDB存储引擎

本文详细介绍了InnoDB存储引擎中事务的四种隔离级别(RU、RC、RR、Series),以及不同级别下的实现原理。重点讨论了锁的种类,如行锁、间隙锁和意向锁,并解释了MVCC如何在RC和RR级别下避免脏读。在RR级别中,通过快照读和Next-Key Lock防止幻读。文章还提供了不同隔离级别下的实例分析,帮助理解其工作方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、隔离级别的种类

RU:未提交读

RC:读提交

RR:可重复读 (默认)

Series:串行化

 

2、锁的种类

行锁,gap lock, next-key lock

共享锁,排他锁,意向共享锁,意向排他锁,插入意向锁

 

意向锁(插入意向锁不包括)之间互相兼容,可以说意向锁就是为了提高锁判断的效率的。两个事务都对同一个表加意向排他锁,也就是两个事务都是修改数据,那么底层的行锁会去再判断。而意向锁最大的意义是:当一个事务要对一个表加排他锁或者是共享锁时,如果没有意向锁的机制,那么他需要去看表里面是否每一行都被加了共享或者排他锁。

 

 

 

 

3、当前读和快照读

当前读:每次读都加锁,不允许其他事务对数据进行修改。比如update,delete, select for update ,select in share mode.读的是最新数据。也叫一致性锁定读。

 

快照读:读的是历史版本。就是通过mvcc实现的。也就一致性非锁定读。

 

4、MVCC

mvcc最大的好处是读不加锁。提高了系统的并发性。同时MVCC也能解决脏读的问题。mvcc在RC和RR级别下也是不同的。RC级别下,读取的是最新提交的记录,未提交的事务数据不读。能避免脏读。RR级别下,只读取事务开始时的快照,所以能够避免不可重复读。

 

实现原理:

在InnoDB中,会在每行数据后添加两个额外的隐藏的值来实现MVCC,这两个值一个记录这行数据何时被创建,另外一个记录这行数据何时过期(或者被删除)。 在实际操作中,存储的并不是时间,而是事务的版本号,每开启一个新事务,事务的版本号就会递增。 在可重读Repeatable reads事务隔离级别下:

SELECT时,读取创建版本号<=当前事务版本号,删除版本号为空或>当前事务版本号。

INSERT时,保存当前事务版本号为行的创建版本号。

DELETE时,保存当前事务版本号为行的删除版本号。

UPDATE时,插入一条新纪录,保存当前事务版本号为行创建版本号,同时保存当前事务版本号到原来删除的行。

通过MVCC,虽然每行记录都需要额外的存储空间,更多的行检查工作以及一些额外的维护工作,但可以减少锁的使用,大多数读操作都不用加锁,读数据操作很简单,性能很好,并且也能保证只会读取到符合标准的行,也只锁住必要行。

 

 

5、不同隔离级别是如何实现的

RU:

为什么会出现脏读?

首先可以确定在RU级别 写是肯定加排他锁的,为什么出现脏读?因为数据库事务的数据对于其他事务都是可见的,只不过不同的隔离级别对其他事务写入的数据做了可见性过滤。比如RC和RR 级别通过MVCC来做。而Serializable是串行化的。所以RU隔离级别下,能直接读到其他活事务提交的数据并且没有做任何过滤,所以会出现脏读。

 

RC:

RC主要避免脏读,MVCC实现的,只能提交的数据。

 

RR:

RR隔离级别能够防止幻读是通过两个手段达到的。

这里区分两种场景,当前读和非当前读。非当前读是通过MVCC来保证的。RR级别的MVCC和RC级别的MVCC不一样,RR级别只读取事务开始时的快照。而RC是读取最新的快照(快照读不加gap锁,所以其他事务是可以继续插入的,只不过在读的时候进行了屏蔽或者说是过滤)。当前读,RR级别通过加next-key lock来避免幻读。这里加了gap锁后,由于插入会加插入意向锁,而插入意向锁和gap锁是不兼容的,当存在gap锁时,是不允许加插入意向锁的。

 

Serializable:

普通的select都加锁,完全串行化了

 

6、几个例子

rc隔离级别下,如果select for update不会加gap锁,其他事务是可以插入的。但是rr级别下是不可以插入的。

 

 

 

 

参考文章:

http://blog.sae.sina.com.cn/archives/2127 讲的非常好了

https://blog.youkuaiyun.com/silyvin/article/details/79320398 脏读怎么出现的?

https://www.aneasystone.com/archives/2017/11/solving-dead-locks-two.html insert intention lock

https://blog.youkuaiyun.com/sun_ashe/article/details/82683296 insert隐式锁

https://chenguoji.com/2019/05/21/mysql-dao-di-shi-zen-me-jie-jue-huan-du-de/ RR级别是如何防治幻读的讲解

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值