在高性能MySQL第三版一书中看到InnoDB通过MVCC解决了幻读的问题,大致原理就是每行存在两个隐藏列,创建版本号和删除版本号,每个事务开始时,都会获得一个系统版本号,系统版本号是递增的。
我们先假设用户表当前只存在一个用户,创建版本号为10
有A、B两个事务经过了如下操作
我们再看当前用户表数据
根据MVCC的规则,SELECT只会找出系统版本号小于等于当前事务版本的数据行,所以问题就来了,id为2的数据是在版本号为11的事务创建的,事务B的版本为12,在T6时刻的SELECT仍然只有一条数据,这确实是解决了幻读,但跟MVCC所说的解决原理不一样啊。
我查了很多解释InnoDB的MVCC的原理的帖子,都没有来解释这个问题,都只是说B事务插入的数据在A事务中找不到而已,而且还有另一个问题就是如果在T4时刻事务B没有进行SELECT操作,那么在T6时刻进行SELECT操作确实有两条数据。