Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
[修改]:修改 事务隔离级别(图文详解) 关于幻读的案例演示和解决方案
  • Loading branch information
wangtong committed Mar 29, 2022
commit f3e1ed6873b23062d4ecf248ae1b8db25532fed0
21 changes: 15 additions & 6 deletions docs/database/mysql/transaction-isolation-level.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ tag:

----

| 隔离级别 | 脏读 | 不可重复读 | 幻影读 |
| 隔离级别 | 脏读 | 不可重复读 | 幻读 |
| :---: | :---: | :---:| :---: |
| READ-UNCOMMITTED | √ | √ | √ |
| READ-COMMITTED | × | √ | √ |
Expand Down Expand Up @@ -127,17 +127,26 @@ SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTE
<div align="center">
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-33-2可重复读.jpg"/>
</div>
#### 幻读

#### 防止幻读(可重复读)
##### 演示幻读出现的情况

<div align="center">
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-33防止幻读(使用可重复读).jpg"/>
</div>
![](http://101.43.132.98:98/images/phantom_read.png)

一个事务对数据库进行操作,这种操作的范围是数据库的全部行,然后第二个事务也在对这个数据库操作,这种操作可以是插入一行记录或删除一行记录,那么第一个是事务就会觉得自己出现了幻觉,怎么还有没有处理的记录呢? 或者 怎么多处理了一行记录呢?
sql 脚本1 在第一次查询工资为 500 的记录时只有一条,sql 脚本 2 插入了一条工资为 500 的记录,提交之后;sql 脚本 1 在同一个事务中再次使用当前读查询发现出现了两条工资为 500 的记录这种就是幻读。

幻读和不可重复读有些相似之处 ,但是不可重复读的重点是修改,幻读的重点在于新增或者删除。

##### 解决幻读的方法

解决幻读的方式有很多,但是它们的核心思想就是一个事务在操作某张表数据的时候,另外一个事务不允许新增或者删除这张表中的数据了。解决幻读的方式主要有以下几种:

1. 将事务隔离级别调整为 `SERIALIZABLE`
2. 在可重复读的事务级别下,给事务操作的这张表添加表锁
3. 在可重复读的事务级别下,给事务操作的这张表添加 `Next-Key Locks`

> 说明:`Next-Key Locks` 相当于 行锁 + 间隙锁

### 参考

- 《MySQL技术内幕:InnoDB存储引擎》
Expand Down