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

mysql-分析并解决可重复读隔离级别发生的删除幻读问题

在 MySQL 的 InnoDB 存储引擎中,快照读和当前读的行为会影响事务的一致性。让我们详细分析一下隔离级别味可重复读的情况下如何解决删除带来的幻读。
场景描述
假设有一个表 orders,其中包含以下数据:
在这里插入图片描述
事务 A 执行快照读

START TRANSACTION;
SELECT * FROM orders WHERE customer_id = 200; -- 快照读

事务 B 执行当前读并删除记录

START TRANSACTION;
DELETE FROM orders WHERE id = 10; -- 当前读,尝试删除
COMMIT;

分析

  • 快照读(事务 A)
  • 快照读:事务 A 执行的是快照读,它基于事务开始时的数据快照,不加锁。
  • 数据快照:事务 A 会看到事务开始时的数据快照,即 customer_id = 200 的记录为 (3, 200, 150) 和 (10,200, 250)。
  • 当前读(事务 B)
  • 当前读:事务 B 执行的是当前读操作,它会尝试获取 id = 10 的记录的行锁。
  • 删除操作:事务 B 成功删除 id = 10 的记录,并提交事务。

影响分析
事务 A 第一次查询:
事务 A 查询 customer_id = 200 的记录,结果为 (3, 200, 150) 和 (10, 200, 250)。
事务 B 删除记录:
事务 B 删除 id = 10 的记录,并提交事务。
事务 A 第二次查询:
事务 A 再次查询 customer_id = 200 的记录,结果为 (3, 200, 150),缺少了 (10, 200, 250)。

结论
幻读:这是因为事务 B 在事务 A 之间删除了一条记录。

解决方案
使用可重复读(Repeatable Read)隔离级别 + 间隙锁

1.设置隔离级别:

SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;

2.使用当前读操作:

  • 在事务 A 中,使用 SELECT … FOR UPDATE 或 SELECT … FOR SHARE 来获取行锁和间隙锁。
  • 这样可以确保在事务 A 的整个生命周期内,查询结果保持一致。

示例
事务 A 执行以下操作:

START TRANSACTION;
SELECT * FROM orders WHERE customer_id = 200 FOR UPDATE; -- 当前读,加锁并获取间隙锁
-- 进行业务逻辑处理
SELECT * FROM orders WHERE customer_id = 200; -- 再次查询
COMMIT;

事务 B 执行以下操作:

START TRANSACTION;
DELETE FROM orders WHERE id = 10; -- 当前读,尝试删除
COMMIT;

由于事务 A 持有 customer_id = 200 范围内的所有记录的行锁和间隙锁,事务 B 的删除操作将被阻塞,直到事务 A 提交或回滚。这样可以确保事务 A 的查询结果在整个事务期间保持一致。

总结
当前读:事务 A 第一次执行的时候使用的是当前读因此会对该行进行加锁,所以其他事务无法对该行进行删除或者更新操作。
快照读:事务 A 第二次执行的时候此时事务并未提交因此使用快照读仍然能读取到该行。
当前读:事务 B 执行当前读并删除记录,由于事务 A 持有锁,导致事务B处于阻塞状态直到事物A释放 。


http://www.kler.cn/a/408442.html

相关文章:

  • 部署一套开源客服系统,用户需要准备什么设备?
  • 产业用机器人中的旋转花键若损伤有何影响?
  • 掌握Go语言中的异常控制:panic、recover和defer的深度解析
  • OCR-free Document Understanding Transformer
  • 7、深入剖析PyTorch nn.Module源码
  • 分公司如何纳税
  • uniapp的列表渲染v-for 与正确写法,循环二维数组
  • 开源网络安全检测工具——伏羲 Fuxi-Scanner
  • 机器学习入门-Scikit-learn
  • 46.坑王驾到第十期:vscode 无法使用 tsc 命令
  • 04 - 尚硅谷 - MQTT 客户端编程
  • 一加ACE 3 Pro手机无法连接电脑传输文件问题
  • Window11+annie 视频下载器安装
  • Sketch在线版不存在?即时设计来填补空白
  • Flink【基于时间的双流联结 Demo】
  • 时序预测 | Matlab实现PSO-Elman粒子群优化递归神经网络时间序列预测
  • raw文件如何打开
  • shell编程之sed
  • 探索 Python 任务自动化的新境界:Invoke 库揭秘
  • 如何用Python统计Excel文件中的特定字段数量
  • 【Java系列】随机生成大小写混合的卡密
  • 大数取模 详解
  • Redis除了做缓存,还能做什么???
  • 密码系统设计实验3-2
  • SQLite 管理工具 SQLiteStudio 3.4.5 发布
  • C语言中的指针和字符串的赋值