# 浅谈MySQL的四种隔离级别

**URL:** <https://www.shiqidu.com/t/topic/751>\
**Category:** 开发调优\
**Tags:** MySQL\
**Created:** [2021 年7 月 13 日 10:02 UTC](https://www.shiqidu.com/t/topic/751 "2021-07-13T10:02:10Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

作者： ![Leon](https://www.shiqidu.com/user_avatar/www.shiqidu.com/leon/32/5_2.png) [@Leon](https://www.shiqidu.com/u/Leon)\
发布日期： [2021 年7 月 13 日 10:02 UTC](https://www.shiqidu.com/t/topic/751/1 "2021-07-13T10:02:10Z")

</div>

众所周知，MySQL的四种隔离级别分别是

1. READ UNCOMMITTED （读未提交）
2. READ COMMITTED （读已提交）
3. REPEATABLE READ （可重复读）
4. SERIALIZABLE （串行化）

从上到下，隔离的级别越来越高，但性能越来越差。MySQL为什么要有隔离性呢？就要引出实际业务中可能出现的问题。

### 脏读

简单理解就是当前同时存在2个及以上的事务，即并发环境下，事务1读取到了事务2中未提交的数据，比如事务2修改`user`表`age`字段从 **1** 改为 **25** ，在事务2还未提交时，这条数据就被事务1读到了。

#### 有什么问题？

假如事务2修改`age`为 **25** 后，因为某些原因回滚了事务，那么事务1读到的 **25** 就是“脏数据”，比如事务1继续拿这个“脏数据”做了一些操作，那么后续的操作都是不合理的。.

**READ UNCOMMITTED （读未提交）** 无法解决脏读的问题

### 不可重复读

这就引出了 **READ COMMITTED （读已提交）** ，read commited 顾名思义就是在一个事务中（只）能读到另一个事务已提交的数据。还是上面的例子，同时存在两个事务，事务1中将`age`字段从 **1** 改为 **25** ，在事务1没有提交之前，事务2中查询到的`age`都是 **1** 。直到事务1提交了，事务2再次读取的`age`才是 **25** ；如此一来就解决了“脏读” 的问题，但是这样就完美了吗？

#### 有什么问题？

仔细考虑我们发现，事务2在一个事务周期的不同时刻，读取的`age`字段是不一样的。在事务1未提交前，读取到的是 **1** ，事务1提交后，读取的到的是 **25** 。这就是不可重复读。

**READ COMMITTED （读已提交）** 无法解决不可重复读的问题

### 幻读

为了解决不可重复读的问题，自然引出 **REPEATABLE READ （可重复读）** ，repeatable read 是什么意思呢，意思就是上面的例子中，事务2，从始至终读取的`age`都是 **1** ，不管事务1有没有提交。

#### 有什么问题？

可重复读解决了不可重复读的问题，但是假如有下面的场景。

同时存在两个事务，事务1查询了`user`表中age=25的数据，现在表里只有一条符合条件数据，自然查出了一条数据，假如现在事务2插入一条age=25的数据，之后事务1又查询了一下age=25的记录，此时发现竟然查出了两条记录，刚才明明还是一条，怎么现在出现了两条。即：本次查询出现了上次查询未出现的记录，像幻觉一样，这就是所谓 **幻读** 。

##### 注意

**REPEATABLE READ （可重复读）** 通过 **MVCC（多版本并发控制）** 和 **GAP LOCK（间隙锁）** 的机制已经解决了幻读的问题。

**SERIALIZABLE （串行化）** 是4种事务隔离级别中隔离效果最好的，解决了脏读、可重复读、幻读的问题，但是性能最差，它将事务的执行变为顺序执行，与其他三个隔离级别相比，它就相当于单线程，后一个事务的执行必须等待前一个事务结束。

### 参考

> **[一文讲清楚MySQL事务隔离级别和实现原理，开发人员必备知识点](https://baijiahao.baidu.com/s?id=1662096005584873447&wfr=spider&for=pc)**

[https://blog.csdn.net/hanpeiyu1995/article/details/90201894](https://blog.csdn.net/hanpeiyu1995/article/details/90201894)
