1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-16 18:10:13 +08:00

[修改]:修改 事务隔离级别(图文详解) 关于幻读的案例演示和解决方案

This commit is contained in:
wangtong 2022-03-29 14:10:54 +08:00
parent a746734c79
commit f3e1ed6873

View File

@ -54,7 +54,7 @@ tag:
---- ----
| 隔离级别 | 脏读 | 不可重复读 | 幻读 | | 隔离级别 | 脏读 | 不可重复读 | 幻读 |
| :---: | :---: | :---:| :---: | | :---: | :---: | :---:| :---: |
| READ-UNCOMMITTED | √ | √ | √ | | READ-UNCOMMITTED | √ | √ | √ |
| READ-COMMITTED | × | √ | √ | | READ-COMMITTED | × | √ | √ |
@ -127,17 +127,26 @@ SET [SESSION|GLOBAL] TRANSACTION ISOLATION LEVEL [READ UNCOMMITTED|READ COMMITTE
<div align="center"> <div align="center">
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-33-2可重复读.jpg"/> <img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-33-2可重复读.jpg"/>
</div> </div>
#### 幻读
#### 防止幻读(可重复读) ##### 演示幻读出现的情况
<div align="center"> ![](http://101.43.132.98:98/images/phantom_read.png)
<img src="https://my-blog-to-use.oss-cn-beijing.aliyuncs.com/2019-33防止幻读(使用可重复读).jpg"/>
</div>
一个事务对数据库进行操作,这种操作的范围是数据库的全部行,然后第二个事务也在对这个数据库操作,这种操作可以是插入一行记录或删除一行记录,那么第一个是事务就会觉得自己出现了幻觉,怎么还有没有处理的记录呢? 或者 怎么多处理了一行记录呢? sql 脚本1 在第一次查询工资为 500 的记录时只有一条sql 脚本 2 插入了一条工资为 500 的记录提交之后sql 脚本 1 在同一个事务中再次使用当前读查询发现出现了两条工资为 500 的记录这种就是幻读。
幻读和不可重复读有些相似之处 ,但是不可重复读的重点是修改,幻读的重点在于新增或者删除。 幻读和不可重复读有些相似之处 ,但是不可重复读的重点是修改,幻读的重点在于新增或者删除。
##### 解决幻读的方法
解决幻读的方式有很多,但是它们的核心思想就是一个事务在操作某张表数据的时候,另外一个事务不允许新增或者删除这张表中的数据了。解决幻读的方式主要有以下几种:
1. 将事务隔离级别调整为 `SERIALIZABLE`
2. 在可重复读的事务级别下,给事务操作的这张表添加表锁
3. 在可重复读的事务级别下,给事务操作的这张表添加 `Next-Key Locks`
> 说明:`Next-Key Locks` 相当于 行锁 + 间隙锁
### 参考 ### 参考
- 《MySQL技术内幕InnoDB存储引擎》 - 《MySQL技术内幕InnoDB存储引擎》