网站首页 > 精选教程 正文
相关的基础知识点就不再详述了,网上资料很多。也可看
可重复读(下文简称RR)理论上是无法解决幻读的,但通过多版本并发控制(下文简称MVCC)、排它锁(下文简称X锁)、临键锁(Next-Key锁,下文简称NK锁)等去尽量地规避幻读。
一、如何规避幻读。
MVCC有两种读取方式:快照读、当前读。
1、如果只是查询,例如
SELECT * FROM table;
这就是快照读,因为MVCC暗含创建版本号(下文简称CV),删除版本号(下文简称DV),SQL语句暗含了
WHERE cv<=当前版本号(即当前事务ID) AND (dv is null OR dv>当前版本号)
后面事务插入的数据读不到,这样就不会产生幻读。
2、如果涉及增删改,就使用当前读。读取最新的数据进行处理,即便是后面事务已提交的数据。例如事务1要更新记录A,但是事务2已经删除了记录A,这就会出问题。
由上可见,当前读是避免不了幻读的。因此加入了NK锁来规避。
假设有字段a=10、20、40、60、70几条记录。
事务1:
SELECT * FROM table WHERE a=40 FOR UPDATE;
这时候InnoDB锁的不仅仅是40这条记录,还会锁(20,40]、(40,60]这两个间隙(GAP)。
事务2,如果INSERT 11或者61,都能成功,但是如果INSERT 21、41就会失败。
所以通过NK锁的排他性,既保证了相关可能产生幻读的记录进不来,也保证了与之无关的数据可以INSERT,提高并发。
二、无法完全避免幻读。
设有如下记录,
id | name | age | cv | dv |
1 | A | 10 | 10 | - |
2 | B | 10 | 10 | - |
事务100:
SELECT * FROM table WHERE age=10;
查询结果为2条记录。
事务200:
INSERT INTO table VALUES (3,C,10);
此时表数据变为:
id | name | age | cv | dv |
1 | A | 10 | 10 | - |
2 | B | 10 | 10 | - |
3 | C | 10 | 200 | - |
事务100:
SELECT * FROM table WHERE age=10;
查询结果仍为2条记录。因为这两次查询都是快照读。
事务100:不加任何条件,将表所有name改为D,
UPDATE table SET name='D';
因为是当前读,所以修改会作用在所有事务提交的数据上,包括事务200新增的数据3,此时表数据变成了:
id | name | age | cv | dv |
1 | A | 10 | 10 | 100 |
2 | B | 10 | 10 | 100 |
3 | C | 10 | 200 | 100 |
1 | D | 10 | 100 | - |
2 | D | 10 | 100 | - |
3 | D | 10 | 100 | - |
事务100:
SELECT * FROM table WHERE age=10;
查询结果为3条记录,出现了幻读。
同理,事务150本来读的是2条,事务100更新之后,也会读出来3条。
事务100前两个SELECT都是快照读,无锁,事务200可以插入,但UPDATE之后,或者假如两个SELECT加了FOR UPDATE,有了NK锁,事务200就无法插入了。
猜你喜欢
- 2024-12-05 Java11新特性-效能翻倍的HttpClient
- 2024-12-05 LeetCode每日一题,无重复字符的最长子串
- 2024-12-05 类型安全的http客户端retrofit介绍、使用、实现原理分析
- 2024-12-05 RabbitMQ消息重复消费问题如何解决
- 2024-12-05 高频面试题:kafka怎么避免重复消费?
- 2024-12-05 RabbitMQ消息丢失、积压、重复等解决方案
- 2024-12-05 程序员们一定要注意避免重复记录日志撑爆ELK而被辞退
- 2024-12-05 面试:如何保证接口的幂等性?常见的实现方案有哪些?
- 2024-12-05 每日分享- 如何保证 Java 语言接口的幂等性?
- 2024-12-05 Kafka如何防止消费速度过慢触发rebalance导致重复消费
你 发表评论:
欢迎- 最近发表
- 标签列表
-
- nginx反向代理 (57)
- nginx日志 (56)
- nginx限制ip访问 (62)
- mac安装nginx (55)
- java和mysql (59)
- java中final (62)
- win10安装java (72)
- java启动参数 (64)
- java链表反转 (64)
- 字符串反转java (72)
- java逻辑运算符 (59)
- java 请求url (65)
- java信号量 (57)
- java定义枚举 (59)
- java字符串压缩 (56)
- java中的反射 (59)
- java 三维数组 (55)
- java插入排序 (68)
- java线程的状态 (62)
- java异步调用 (55)
- java中的异常处理 (62)
- java锁机制 (54)
- java静态内部类 (55)
- java怎么添加图片 (60)
- java 权限框架 (55)
本文暂时没有评论,来添加一个吧(●'◡'●)