当前位置: 首页 > news >正文

MySQL-事物隔离级别

1. MySQL事物的四种隔离级别

1.1 读未提交(READ UNCOMMITTED)

READ UNCOMMITED提供了事物之间最小限度的隔离,除了幻读和不可重复读取的操作外,处于这个隔离级别的事务可以读到其它事务还未提交的数据。

1.2  读已提交(READ COMMITTED)

处于READ COMMITTED隔离级别的事务可以读取到其它事务对数据的修改。也就是说,在处理事务期间,如果其他事务修改了相应的表(已提交),那么同一个事务的多次SELECT执行可能返回不同的结果。

1.3 可重复读(REPEATABLE READ)

可重复读隔离级别上,当前正在执行事务的变化不能被其它事务看到,也就是说,同一个事务的多次SELECT执行结果是相同的。

1.4 串行化(SERIALIZABLE)

串行化,事务之间一个接一个的执行,这种隔离级别提供了事物之间最大限度的隔离。

2. 通过例子理解脏读、不可重复读、幻读

2.1 读未提交隔离级别下脏读、不可重复读、幻读

2.1.1 准备测试数据

设置事务隔离级别为READ UNCOMMITTED

-- 在DBeaver打开2个SQL编辑窗口(不同的session),各执行如下语句。
-- 将两个SESSION的事务隔离级别设置为读未提交
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;

创建一张用户表t_user,预插入两条数据,如表格:

2.1.2 脏读

脏读,在一个事务中可以读取到另一个事务还未提交的数据。

窗口A

--事务A
line1: START TRANSACTION;
line2: INSERT INTO t_user(id, user_name, balance) VALUES (3, '王五', 1000);
line3: COMMIT;

窗口B

-- 事务B
line1: START TRANSACTION;
line2: SELECT * FROM t_user;
line3: COMMIT;

测试步骤:

a) 窗口A执行line1, line2, 插入用户“王五”,先不执行提交

b) 窗口B执行line1,line2时,可以看到用户“王五”,而此时窗口A尚未提交事务,产生了脏读

2.1.3 不可重复读

不可重复读,在一个事务中多次执行SELECT语句,返回的结果不相同。

A窗口

-- 事务A
line1: START TRANSACTION;
line2: INSERT INTO t_user(id, user_name, balance) VALUES (3, '王五', 1000);
line3: INSERT INTO t_user(id, user_name, balance) VALUES (4, '赵六', 1000);
line4: COMMIT;

B窗口

-- 事务B
line1: START TRANSACTION;
line2: SELECT * FROM t_user;
line3: SELECT * FROM t_user;
line4: COMMIT;

执行步骤

a) A窗口执行line1, line2语句,B窗口执行line1, line2语句,此时B窗口可以读取到“王五”。

b) A窗口接着执行line3, B窗口执行line3,此时B窗口可以读取到“王五”和“赵六”

两次SELECT查询结果不一致,所以是不可重复读

2.1.4 幻读

幻读与不可重复读比较像。事务比做人的话,就是当前事务产生幻觉了。

窗口A

--事务A
line1: START TRANSACTION;
line2: INSERT INTO t_user(id, user_name, balance) VALUES (3, '王五', 1000);
line3: COMMIT;

窗口B

-- 事务B
line1: START TRANSACTION;
line2: SELECT * FROM t_user;
line3: DELETE FROM t_user WHERE id = 3;
line4: COMMIT;

执行步骤

a) A窗口执行line1, line2,B窗口执行line1, line2 , 可以读取到“王五”

b) B窗口继续执行line3,发现执行删除操作一直在等待,无法完成删除。原因是因为id=3的记录在窗口A尚未提交,脏读导致可以被窗口B看到,所以是无法删除的。此时就产生了幻觉,明明有id=3的记录,却无法删除。

2.2 读已提交隔离级别下脏读、不可重复读、幻读

2.2.1 设置事务隔离级别为READ COMMITTED

-- 在DBeaver打开2个SQL编辑窗口(不同的session),各执行如下语句。
-- 将两个SESSION的事务隔离级别设置为读已提交
SET SESSION TRANSACTION ISOLATION LEVEL READ COMMITTED;

2.2.2 脏读

窗口A

--事务A
line1: START TRANSACTION;
line2: INSERT INTO t_user(id, user_name, balance) VALUES (3, '王五', 1000);
line3: COMMIT;

窗口B

-- 事务B
line1: START TRANSACTION;
line2: SELECT * FROM t_user;
line3: COMMIT;

执行步骤:

a) 窗口A执行line1, line2 ,窗口B执行line1, line2看不到用户“王五”

b) 窗口A执行line3, 窗口B再次执行line2,此时可以看到用户“王五”,所以不存在脏读问题

2.2.3 不可重复读

窗口A

--事务A
line1: START TRANSACTION;
line2: INSERT INTO t_user(id, user_name, balance) VALUES (3, '王五', 1000);
line3: COMMIT;

窗口B

-- 事务B
line1: START TRANSACTION;
line2: SELECT * FROM t_user;
line3: COMMIT;

执行步骤:

a) 窗口B执行line1, line2,此时看不到用户“王五”

b) 窗口A执行line1, line2, line3

c) 窗口B再次执行line2,此时可以看到用户“王五”,两次SELECT的结果不一致,所以是不可重复读

2.2.4 幻读

窗口A

--事务A
line1: START TRANSACTION;
line2: INSERT INTO t_user(id, user_name, balance) VALUES (3, '王五', 1000);
line3: COMMIT;

窗口B

-- 事务B
line1: START TRANSACTION;
line2: SELECT * FROM t_user;
line3: INSERT INTO t_user(id, user_name, balance) VALUES (3, '王五', 1000);
line4: COMMIT;

执行步骤:

a) 窗口B执行line1,line2,此时没有看到用户“王五”

b) 窗口A执行line1, line2, 插入用户“王五”

c) 窗口B执行line3时会一直等待窗口A的事务提交或回滚。在这里窗口B产生了幻觉,明明执行SELECT没有看到用户“王五”,但是插入不成功。

2.3 REPEATABLE READ

和READ COMMITTED相比,REPEATTED READ进一步解决了不可重复读问题,但是幻读则未能解决。REPEATABLE READ中关于幻读的测试与上一小节基本一致,不同的是在步骤b中执行到line3提交事务。由于REPEATABLE READ已经解决了不可重复读,因此步骤b即使提交了事务,SELECT也查不出已经提交的数据。继续插入会报错。

2.4 SERIALIZABLE

SERIALIZABLE提供了事务之间最大限度的隔离,在这种隔离级别中,事务一个接一个的顺序执行,不会发生脏读,不可重复读以及幻读,最安全。

如果设置当前事务隔离级别为SERIALIZABLE,那么此时开启其它事务时,就会阻塞,必须等当前事务结束了,其它事务才能开启成功,因此前面的脏读,不可重复读,幻读问题在这个隔离级别下不会发生。

3. 总结

3.1 隔离级别与脏读、不可重复读、幻读的关系如下

隔离级别脏读不可重复读幻读
READ UNCOMMITTED允许允许允许
READ COMMITTED不允许允许允许
REPEATABLE READ不允许不允许允许
SERIALIZABLE不允许不允许不允许

3.2 隔离级别与性能之间的关系


http://www.mrgr.cn/news/56589.html

相关文章:

  • 个税自然人扣缴客户端数据的备份与恢复(在那个文件夹)
  • c++面试八股
  • 本地图像转base64-cnblog
  • autMan框架对接飞书机器人
  • 监控易监测对象及指标之:Kafka中间件JMX监控指标解读
  • U-Boot的移植流程
  • C++ —— 实现一个日期类
  • 使用Mock库进行依赖注入的实用指南
  • TinyC编译器5—词法分析
  • git 下载慢
  • input标签v-model属性失效
  • 信发软件之展示excel文档——未来之窗行业应用跨平台架构
  • 图像处理学习笔记-20241021
  • Ubuntu配置FTP
  • eCAP超声波测距-ePWM电机调速
  • 影刀RPA实战:网页爬虫之我爱听评书
  • 数据结构 - 树,三探之代码实现
  • 如何看待AI技术的应用前景?
  • AI处理图片和视频的网址
  • 帝国CMS – AutoTitlePic 自动生成文章标题图片插件
  • ARL 灯塔 | ARL 灯塔 — 字典替换
  • 路径参数和post请求方式在请求资源时如何选择------各自的优势和使用场景比较
  • 基于深度学习的声纹识别
  • 进销存平板展示系统——未来之窗行业应用跨平台架构
  • 要让AI(任何一款绘图AI)把一个己有风格的图片画到一个实物商品上的窍门
  • 压缩感知方法——基础追踪(Basis Pursuit, BP)方法详解