MYSQL幻读问题

本文解释了幻读现象,即在InnoDB存储引擎中,事务A可能在事务B插入新记录后读取到不同数据。通过介绍RR级别下的Next-KeyLocking机制,如何使用FORUPDATE语句锁定数据范围以避免幻读。
摘要由CSDN通过智能技术生成

幻读是什么?

“Phantom Problem是指在同一事务下,连续执行两次同样的SQL语句可能导致不同的结果,第二次的SQL语句可能会返回之前不存在的行。”摘录来自 MySQL技术内幕:InnoDB存储引擎(第2版) (数据库技术丛书)

​ 通俗来说就是,time1:事务A读取某个范围,time2:事务B在这个范围中插入了一条新记录并提交事务,time3:事务A再次读取该范围的记录时读取到事务B新增的记录。

如下:

目前InnoDB存储引擎中,数据库有表如下:

-- ----------------------------
-- Table structure for film
-- ----------------------------
DROP TABLE IF EXISTS `film`;
CREATE TABLE `film` (
  `id` int NOT NULL AUTO_INCREMENT,
  `name` varchar(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb3;

-- ----------------------------
-- Records of film
-- ----------------------------
BEGIN;
INSERT INTO `film` (`id`, `name`) VALUES (1, 'film1');
INSERT INTO `film` (`id`, `name`) VALUES (2, 'film2');
COMMIT;

Time1: 开启事务A , 查询表film中的所有记录。

在这里插入图片描述

Time2:在film表中插入一条ID 为 3的记录

在这里插入图片描述

Time3: 事务A查询表film中所有的数据;注意这时select出的记录中是没有ID为3的记录。

在这里插入图片描述

但是我们会发现update ID 为3的记录是成功的,也就是说事务A是可以感知到事务B新增的ID为3的记录。

在这里插入图片描述

这时再去读区数据发现是可以读取到的

在这里插入图片描述

这就是幻读问题。

如何避免幻读问题?

在RR级别下,采用Next-Key Locking的算法避免幻读问题,即使用FOR UPDATE。

SELECT * FROM film FOR UPDATE;

对于上面的SQL语句,会将(-∞,+∞)这个范围加锁,因此在这个范围内的插入都是不允许的,从而避免幻读。当然如果是id > 2 范围查找那么锁住的也就是(2,+∞)。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值