导致幻读的根本原因是:在大多数情况下,快照读是通过读取已经存在的快照来获取数据的,而不会触发当前读。有一种情况可以导致在 RR 隔离级别下触发当前读绕过快照读,那就是使用了锁定行的语句,如 SELECT ... FOR UPDATE 或 SELECT ... LOCK IN SHARE MODE。所以update 触发的当前读操作,绕过了快照读,从而导致 MVCC机制在当前场景下失效。最终读取到了事务 2中已经提交的数据。
为了避免出现这类的情况,我们可以通过 for update 语句加锁。