mysql 默认事务隔离级别_图解 MySQL 事务隔离级别

图解 MySQL 事务隔离级别

4 种隔离级别

InnoDB 引擎中的事务隔离级别有 4 级,默认是"可重复读"(Repeatable Read)。以下 4 个级别逐渐加强,每个级别都解决了上一个级别的问题,但也留下了新的问题。

脏读(Read Uncommitted-读未提交)

一个事务在处理过程中读取了另外一个事务未提交的数据。

f66b8abc362d44dbfdd7610e30e5b833.png

事务 1 更新数据后还未提交,事务 2 就读到了该数据,所以叫 read uncommitted

读提交(Read Committed)

读取的数据是其它事务提交后的数据。

3475cb37b83c29df4a04e6da94981953.png

事务 1 更新了数据,但还未提交,这时事务 2 读取到的数据是更新之前的。

在事务 1 提交后,事务 2 再读取,此时读取到的就是事务 1 更新后的数据。

这里就有一个问题:::在同一事务过程中,多次读取到的数据是不一致的::。所以又叫"不可重复读"。

可重复读(Repeatable Read)

在同一事务中,每次读取的数据是一致的。

c2295d1c744c502eb5b217bbfa7ec8a4.png

即使事务 1 提交了,事务 2 读取的数据和事务 2 开始时间点的数据是一致的。

但这是也有一个问题:::如果事务 2 根据查询出的结果进行更新,那么会发现更新时的数据已经变成事务 1 更新后的数据了,而不是事务 2 查询出的数据::。这就是"幻读"。

串行化

各事务间互斥。即使是读操作也会互斥。

dc9b123e11ba8f4964b205b827b0f2d7.png

验证默认情况下的幻读问题

默认情况下的级别是可重复读,这种情况下可能会产生幻读。以下是复现的步骤:

数据库版本是 v8.0.13。

新建一张表:

mysql> create table users (id int(4) not null primary key auto_increment, name char(20) not null);
Query OK, 0 rows affected (0.04 sec)

然后使用两个客户端来分别执行命令,这两个客户端的隔离级别都是"可重复读":

mysql> select @@transaction_isolation;
+-------------------------+
| @@transaction_isolation |
+-------------------------+
| REPEATABLE-READ         |
+-------------------------+

下面使用图示的方式来展示两个客户端执行的命令以及命令的结果:

e3e60a7760fccabc6da13ed37d54b6fd.png

事务 2 在 insert 前后都没有查询出数据,但是 insert 依然显示主键冲突。

在 select 时加锁

select 语句中添加 for update 可以为数据集添加共享锁,其它事务就没有办法更新该数据集了。

以下演示:在两个事务中都使用 for update:

5149d8f75034ae100d72c89b25cbb58a.png
  1. 两个事务在开始时都使用 for update 加锁;
  2. 事务 1 在更新数据集时会等待事务 2 释放锁,这里 insert 命令会阻塞住。
  3. 事务 2 使用 insert 更新时会显示出现死锁,然后结束事务。
  4. 事务 1 等到事务 2 结束后才会显示更新成功。

如果 for update 在对方 insert 之后:

ab8115c69d2d1e99edee7aa10e31c95f.png
  1. 事务 2 的 for update 会等待事务 1 释放锁。
  2. 事务 1 结束。
  3. 事务 2 的 select 获得了最新的数据。

以下演示:只在其中一个事务中使用 for update:

74d5bf80121e2e5c860de9867631454f.png
  1. 事务 1 使用 for update 加锁,事务 2 不使用。
  2. 事务 2 使用 insert 更新数据,这时会阻塞住等待锁释放。
  3. 事务 1 也使用 insert 更新数据,并且成功了。事务 1 接着使用 commit 结束事务。
  4. 事务 2 在事务 1 结束事务释放锁后,显示已经存在相关数据了。事务 2 出现了::幻读::。

首发于微信公众号:漂泊尘埃

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值