MySQL 在默认的事务隔离级别下到底有没有解决幻读问题啊
1 iseki 2020-07-23 09:28:36 +08:00 via Android 没有吧 |
2 zarte 2020-07-23 09:29:41 +08:00 只是事务解决不了并发 |
3 iseki 2020-07-23 09:30:01 +08:00 via Android 你看看 PostgreSQL…那个没有…有谓词锁 |
4 pingdongyi 2020-07-23 09:30:25 +08:00 via Android 看如何定义幻读 |
6 nwg 2020-07-23 09:31:21 +08:00 插入类型的幻读解决不了 比如:预定会议室问题 更新类别的幻读解决了 多次查询是一个数据 |
7 xuwei0056 2020-07-23 09:32:42 +08:00 解决了 |
![]() | 8 BBCCBB 2020-07-23 09:32:45 +08:00 ![]() 解决了, 有 gap lock. |
9 ylsc633 2020-07-23 09:32:59 +08:00 |
![]() | 10 birdkyle79 2020-07-23 09:47:23 +08:00 ![]() 解决了。 在非锁定读的情况下会读取一个快照数据,不会出现幻读。 在锁定读的情况下会有间隙锁,也不会出现幻读。 PS:推荐看一看《 MySQL 技术内幕 InnoDB 存储引擎》 |
![]() | 11 RedBeanIce 2020-07-23 09:55:35 +08:00 mvcc,间隙锁(书上看的) |
12 huntcool001 2020-07-23 10:05:01 +08:00 ![]() 没有完全解决. StackoverFlow 上这个例子: https://stackoverflow.com/questions/5444915/how-to-produce-phantom-reads create table ab(a int primary key, b int); Tx1: begin; select * from ab; // empty set Tx2: begin; insert into ab values(1,1); commit; Tx1: select * from ab; // empty set, expected phantom read missing. update ab set b = 2 where a = 1; // 1 row affected. select * from ab; // 1 row. phantom read here!!!! |
![]() | 13 lscexpress 2020-07-23 10:15:25 +08:00 幻读影响你业务吗? |
![]() | 14 hheedat 2020-07-23 10:25:17 +08:00 解决了 MVCC + gap lock |
15 maigebaoer 2020-07-23 10:32:31 +08:00 via Android 并没有 |
16 jimmyismagic 2020-07-23 10:35:48 +08:00 默认并没有解决幻读,因为只锁了行,对于批量处理,你可能在删了一批符合条件的数据后,又读到新的符合条件的数据 |
![]() | 17 F281M6Dh8DXpD1g2 2020-07-23 10:41:30 +08:00 via iPhone 没有 新增的不会看到 update 的会有问题 |
18 gadsavesme 2020-07-23 10:46:29 +08:00 快照读解决,当前读还是有问题 |
19 pangleon 2020-07-23 11:07:22 +08:00 MYSQL 用间隙锁解决幻读问题,结果间隙锁又会引起别的 BUG,所以 RR 级别很多公司都不推荐使用。都是用 RC 了,毕竟人家 ORACLE 就是默认 RC 有谁去改了么? |
20 gotonull OP @lscexpress 没有,只是面试的时候被问到了,我说没解决,面试官说解决了。所以来问问大神们。结果大家的回答还是各种说法都有,都给我整懵了! |
![]() | 22 mahone3297 2020-07-23 11:17:41 +08:00 极客时间,Mysql 的课有讲,解决了。 20 | 幻读是什么,幻读有什么问题? |
23 zgzhang 2020-07-23 11:29:59 +08:00 ![]() 在快照读读情况下,mysql 通过 mvcc 来避免幻读。 在当前读读情况下,mysql 通过 next-key 来避免幻读。 select * from t where a=1;属于快照读 select * from t where a=1 lock in share mode;属于当前读 不能把快照读和当前读得到的结果不一样这种情况认为是幻读,这是两种不同的使用。所以我认为 mysql 的 rr 级别是解决了幻读的。 https://github.com/Yhzhtk/note/issues/42 |
24 gotonull OP @mahone3297 谢谢,这就去学习学习 |
![]() | 25 dxyhymn 2020-07-23 13:46:29 +08:00 解决了,推荐去看书,看完你就知道了,而且很透彻。 |
26 JasonLaw 2020-07-23 14:29:21 +08:00 @huntcool001 #12 +1,并没有完全解决。 https://dev.mysql.com/doc/refman/8.0/en/innodb-consistent-read.html 中也描述了这个问题。在“The snapshot of the database state applies to SELECT statements within a transaction, not necessarily to DML statements.”这段里面。 |
27 JasonLaw 2020-07-23 14:35:34 +08:00 其实我不太明白为什么这么多人都是在说 gap locking,文档里明明说的是 next-key locking 。 https://dev.mysql.com/doc/refman/8.0/en/innodb-next-key-locking.html 中说了“To prevent phantoms, InnoDB uses an algorithm called next-key locking that combines index-row locking with gap locking.”,很明显,单纯的 gap locking 是不能阻止幻读的,index-row locking 加上 gap locking 才能够解决。 |
29 pws22 2020-07-23 14:45:09 +08:00 没有完全解决 |
30 daimubai 2020-07-23 22:30:09 +08:00 via iPhone 确实使用的是 Next-lock-key 算法,它包含了 row lock 和 gap lock,默认情况下是解决了幻读的,不过不能完全避免吧,因为只会锁间隙,如果不在间隙添加也可以添加成功吧 |
31 daimubai 2020-07-23 22:31:21 +08:00 via iPhone MVCC 并没有解决幻读,而是解决了 RC 下的脏读和 RR 下的不可重复读 |
32 wentaoliang 2020-07-23 23:00:33 +08:00 默认没有开启避免幻读,但是可以通过 for update 或者 share mode 来开启避免幻读。原理楼上以及说了 |
![]() | 33 freelancher 2020-07-24 06:48:37 +08:00 讲真。我看原理的时候就解决了。这个是在隔离特性里面。自己去看一下吧。 |
34 leapV3 2020-07-24 10:20:16 +08:00 可重复读没有解决,需要加间隙锁 |