1.什么是幻读?
| 时刻 | 事务A | 事务B |
| T1 |
begin; select * from t where id = 1; | |
| T2 |
begin; insert into t values(1,1); commit; | |
| T3 | update set d = 5 where id=1; | |
| T4 | select * from t where id=1; |
事务A在T1时刻查询id=1的记录是查询不到数据的,然后事务B在T2时刻插入了一条id=1的数据,然后事务A在T3时刻更新id=1的记录成功了,最后事务A在T4时刻查询id=1的记录能够查询到,这个案例就是幻读的一种;
因为按照可重复读的隔离级别规则:同一条查询语句在事务中执行的不同时刻结果应该是一样的,但是在T1、T4时刻执行同一条查询语句得到的结果不一样,就让人感觉产生了幻觉,这就是幻读。
2.那如何解决幻读呢?
(1)把隔离级别设置为串行化,但是这样的话效率就比较低了,只能先执行完A事务才能执行B事务;
(2)在可重复读的隔离级别下,mysql的innodb引擎引入了间隙锁,在一定程度了解决了幻读问题。
使用如下形式查询可以解决幻读:
| 时刻 | 事务A | 事务B |
| T1 |
begin; select * from t where id = 1 for update; | |
| T2 |
begin; insert into t values(1,1); commit; | |
| T3 | update set d = 5 where id=1; | |
| T4 | select * from t where id=1 for update; |
博客介绍了MySQL中的幻读现象,如事务A在不同时刻查询id=1的记录结果不同,这违背了可重复读隔离级别规则。还给出了解决幻读的方法,一是将隔离级别设为串行化,但效率低;二是在可重复读隔离级别下,innodb引擎用间隙锁一定程度解决问题。
2万+

被折叠的 条评论
为什么被折叠?



