栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mysql的可重复读隔离级别下使用快照读可以避免出现幻读。mvcc(多版本并发控制)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mysql的可重复读隔离级别下使用快照读可以避免出现幻读。mvcc(多版本并发控制)

幻读

在一个事务中查询多次会出现不一样数目的结果集。

结论

在快照读情况下,可重复读可以避免幻读(MVCC)
在当前读情况下,可重复读还是会出现幻读。

当前读和快照读是针对某一行记录来说的。一个范围查询中当前读和快照读可以同时存在的

解释 快照读

快照读又叫一致性读,读取的是快照数据。不加锁的简单的 SELECt 都属于快照读,即不加锁的非阻塞读;普通的select *。。。。

当前读

当前读读取的是记录的最新版本(最新数据,而不是历史版本的数据),读取时还要保证其他并发事务不能修改当前记录,会对读取的记录进行加锁。加锁的 SELECT,或者对数据进行增删改都会进行当前
读。比如:

SELECT * FROM student LOCK IN SHARE MODE;  # 共享锁
SELECt * FROM student FOR UPDATe; # 排他锁
INSERT INTO student values ...  # 排他锁
DELETE FROM student WHERe ...  # 排他锁
UPDATe student SET ...  # 排他锁
MVCC

MVCC (Multiversion Concurrency Control),多版本并发控制。顾名思义,MVCC 是通过数据行的多个版本管理来实现数据库的 并发控制 。这项技术使得在InnoDB的事务隔离级别下执行 一致性读 操作有了保证。
可重复读隔离级别下的快照读,一个事务中查询语句会产生一个快照ReadView。然后每次查询都查不到之后新增或者修改的数据。

验证结论 表结构
CREATE TABLE `course` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `course_id` int(11) NOT NULL,
  `course_name` varchar(40) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=217 DEFAULT CHARSET=utf8;
事务演示
时刻事务1事务2事务1结果
t1BEGIN;没开始
t2select * FROM course;BEGIN;查询出1条数据
t3select * FROM course;INSERT INTO course (course_id,course_name) values(6,‘事务2’);查询出1条数据
t4COMMIT;
t5select * FROM course;查询出1条数据
t6UPDATe course set course_name=‘sqqs’ where course_id =6修改影响1行
t7select * FROM course;查询出2条数据

事务1在【t5】时刻查询还是一条数据,证明在可重复读下快照读不会出现幻读。
事务1在【t6】时刻进行了修改操作使得【course_id=6】(事务2在t4时刻提交的数据)变成了当前读。所以在【t7】时刻再读取时就读取到了course_id=6的数据。

时刻结果图 t1-t2时刻事务1查数据

t2-t4时刻-事务2进行插入数据

t5时刻事务1查数据

在t1-t2同一个事务下查询,这里是选择执行了,如下图。
结果还是一条数据,没有出现幻读。

t6时刻

事务1执行了修改操作使得course_id=6的数据变成了当前读。

t7时刻

因为t6时刻把course_id=6变成了当前读导致读取最新数据,所以出现了两条数据,造成了幻读现象。

最后结论

不能认为可重复读就一定会出现幻读问题,必须要上串行化级别才能解决幻读问题。
在快照读情况下,可重复读可以避免幻读(MVCC)
在当前读情况下,可重复读还是会出现幻读,要串行化级别才能解决。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/888012.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号