对于幻读的理解

2020-12-28  本文已影响0人  倚仗听江

定义:事务A 按照一定条件进行数据读取, 期间事务B 插入了相同搜索条件的新数据,事务A再次按照原先条件进行读取时,发现了事务B新插入的数据称为幻读。(读到了其他事务新插入的数据)
创建表和数据(Mysql 隔离级别为 可重复读)

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` bigint(10) NOT NULL,
  `username` varchar(50) DEFAULT NULL,
  `age` int(10) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'zhuangsan', '17');
INSERT INTO `user` VALUES ('2', 'lisi', '18');
INSERT INTO `user` VALUES ('3', 'wangwu', '18');

进行以下的操作:
A事务

BEGIN
-- T1时刻A事务查询所有年龄为18的用户
SELECT * FROM `user` where age = 18

-- T3时刻A事务查询所有年龄为18的用户
SELECT * FROM `user` where age = 18

-- T4时刻更新所有年龄为18的用户
UPDATE `user` SET username = 'ss' WHERE age = 18

-- T5时刻A事务查询所有年龄为18的用户
SELECT * FROM `user` where age = 18

B事务

-- T2时刻,B事务插入一条数据
INSERT INTO `user` VALUES (4,'sherlock',18)

在T1~T3时刻,可重复读隔离级别下貌似没有幻读问题,但实则不然。在T4时刻的影响条数是3条,T5时刻查出来的数据也是三条,产生了幻读的问题。

那么在可重复读级别下,能否解决幻读的问题呢?
答案是可以的。可重复读隔离级别下,一个事务中只使用当前读,或者只使用快照读都能避免幻读。
在快照读读情况下,Mysql通过MVCC来避免幻读。
在当前读读情况下,Mysql通过next-key来避免幻读。

什么是快照读和当前读

  1. 快照读:简单的select操作,属于快照读,不加锁。
  1. 当前读:特殊的读操作,插入/更新/删除操作,属于当前读,需要加锁。
上一篇 下一篇

猜你喜欢

热点阅读