> For the complete documentation index, see [llms.txt](https://bohans.gitbook.io/ji-chu/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bohans.gitbook.io/ji-chu/mysql/ji-chu-zhi-shi/shi-wu/ge-li-ji-bie.md).

# 隔离级别

### READ UNCOMMITTED（读未提交）

在 <mark style="color:blue;">**READ UNCOMMITTED**</mark> 级别，<mark style="color:blue;">**在事务中可以查看其他事务中还没有提交的修改**</mark>。

**读取未提交的数据，也称为**<mark style="color:blue;">**脏读(dirty read)**</mark>**。**

### READ COMMITTED（读已提交）

<mark style="color:blue;">**READ COMMITTED**</mark> 满足前面提到的隔离性的简单定义：<mark style="color:blue;">**一个事务可以看到其他事务在它开始之后提交的修改，但在该事务提交之前，其所做的任何修改对其他事务都是不可见的。**</mark>

这个级别仍然允许**不可重复读（nonrepeatable read）**，这意味着**同一事务中两次执行相同语句，可能会看到不同的数据结果**。

## REPEATABLE READ（可重复读）

<mark style="color:blue;">**REPEATABLE READ**</mark> 解决了 READ COMMITTED 级别的不可重复读问题，保证了<mark style="color:blue;">**在同一个事务中多次读取相同行数据的结果是一样的**</mark>。

理论上，可重复读隔离级别无法解决<mark style="color:blue;">**幻读（phantom read）**</mark>问题。所谓幻读，**指的是当某个事务在读取某个范围内的记录时，另外一个事务又在该范围内插入了新的记录，当之前的事务再次读取该范围的记录时，会产生幻行（phantom row）。**

{% hint style="success" %}
**InnoDB 和 XtraDB 存储引擎通过**<mark style="color:blue;">**多版本并发控制（MVCC，Multiversion Concurrency Control）**</mark>**解决了幻读的问题。**
{% endhint %}

## SERIALIZABLE（可串行化）

<mark style="color:blue;">**SERIALIZABLE**</mark> 是最高的隔离级别。<mark style="color:blue;">**该级别通过强制事务按序执行，使不同事务之间不可能产生冲突**</mark>，从而解决了前面说的幻读问题。简单来说，SERIALIZABLE 会在读取的每一行数据上都加锁，所以可能导致大量的超时和锁争用的问题。

<table><thead><tr><th>隔离级别</th><th data-type="checkbox">脏读</th><th data-type="checkbox">不可重复读</th><th data-type="checkbox">幻读</th><th data-type="checkbox">加锁读</th></tr></thead><tbody><tr><td>未提交读</td><td>true</td><td>true</td><td>true</td><td>false</td></tr><tr><td>提交读</td><td>false</td><td>true</td><td>true</td><td>false</td></tr><tr><td>可重复读</td><td>false</td><td>false</td><td>true</td><td>false</td></tr><tr><td>可串行化</td><td>false</td><td>false</td><td>false</td><td>true</td></tr></tbody></table>

{% hint style="info" %} <mark style="color:blue;">**REPEATABLE READ 是 MySQL 默认的事务隔离级别。**</mark>

MySQL 可以通过执行 <mark style="color:blue;">**SET TRANSACTION ISOLATION LEVEL**</mark> 命令来设置隔离级别。新的隔离级别会在下一个事务开始的时候生效。

可以在配置文件中设置整个服务器的隔离级别，也可以只改变当前会话的隔离级别：

```sql
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
```

{% endhint %}
