不同引擎mvcc实现不一样。以innodb为例的话,mvcc本身是通过trx_id(事务隐藏列)来实现的版本维护,不能读取到ReadView开启时还没提交的事务的记录。
mysql里面实际上有两种读,一种是“快照读”,比如我们使用select进行查询,就是快照读。在快照读的情况下不会产生幻读的问题。
另一种读则是“当前读”,例如delete,update,insert等语句,都需要满足直接忽略事务号读取最新数据的要求。
否则可能产生下述情况:
在执行这几个操作时会读取最新的记录,即使是别的事务提交的数据也可以查询到。比如要update一条记录,但是在另一个事务中已经delete掉这条数据并且commit了,如果update就会产生冲突,所以在update的时候需要知道最新的数据。读取的是最新的数据,并且需要加锁(排它锁或者共享锁)。
因此可以通过下面的方法绕开版本号限制,产生幻读问题:
通过update把新传进来的事务id为200的数据更新为事务id为100,进而id为100的事务可以读取事务id为100的数据,绕了下成功读取insert的新数据。
参考链接:
MVCC能否解决幻读 - xuwc - 博客园