在MYSQL的事务引擎中,INNODB是使用范围最广的。它默认的事务隔离级别是REPEATABLE READ(可重复读),在标准的事务隔离级别定义下,REPEATABLE READ是不能防止幻读产生的。INNODB使用了2种技术手段(MVCC AND GAP LOCK)实现了防止幻读的发生。现在的问题是,光MVCC就能够防止幻读了,为什么在加锁的时候还要使用GAP LOCK??
这一块,你的理解可能有误, select: Its creation id must be less than or equal to the system version number. This ensures that the row was created before the current query began. 这里只是说系统版本号,应该是所有会话的最大的事务版本号INSERT When a row is added to a table, the database server records the current version number along with the new row, using it as the row's creation id. 这里才说是当前版本号,应该是当前会话的还是有区别的。
如果没有gap lock就只能锁定读取或写入的行,如果一个事务id较小的事务插入了间隔的行,原事务再查询时,会不会就产生了幻想读呢?
就算插入的是间隙里面,插入行的版本也比当前事务的版本要高,MVCC规则下是也是查不出来的。
我也迷糊着。
MVCC不加锁,GAP LOCK加锁。gap lock在写的时候就锁定了间隙,幻读行是无法插入的。MVCC是在读的时候筛选某些数据,都能够防止幻读。
提交后的数据行版本就大于当前的事务版本了呀。在INSERT的时候,INNODB为每个新增行记录当前的系统版本号。
这一块,你的理解可能有误,
select: Its creation id must be less than or equal to the system version number. This ensures that the row was created before the current query began.
这里只是说系统版本号,应该是所有会话的最大的事务版本号INSERT
When a row is added to a table, the database server records the current version number along with the new row, using it as the row's creation id.
这里才说是当前版本号,应该是当前会话的还是有区别的。