我的理解是:间隙锁只能保证范围内的键不被插入,无法保证范围内的键不被删除。如果在事务执行期间另一个事务删除了该范围内的某一行数据,原事务再次查询时就会发现出现了幻读。
比如索引1,3有数据,然后加了间隙锁,那么查询1-3之间的数据的时候,会查询到两条记录。并且因为间隙锁的存在,所以无法添加数据。但是索引1或者3本身所代表的数据可能会被删除,所以再次查询的时候会只查询到1条或者0条记录。
因为间隙锁只能锁定存在的间隙,而不能锁定不存在的间隙。
如果一个事务正在读取某个表中的所有记录,并且在事务执行期间另一个事务插入了一些新的记录,那么间隙锁将无法防止第一个事务读取新插入的记录。
你好,感谢回复!但我还是不理解。间隙被锁住了,如果添加了新的记录,显然间隙会变化,但是加了间隙锁,这是不被允许的啊。
@yyyyyu: 间隙被锁住了,如果添加了新的记录,显然间隙会变化,但是加了间隙锁,这是不被允许的啊。,间隙锁被释放了。
@luzemin: A事务正在读取某个表中的所有记录,并且在事务执行期间另一个事务(B事务)插入了一些新的记录。对于这种场景,在A事务提交之前,间隙锁不会被释放吧?间隙锁没有释放那么就不能添加记录啊。因为添加记录会导致间隙发生变化。
@yyyyyu: 间隙锁只能保证锁住的间隙内不允许增删改。
间隙外的新增,怎么会导致间隙范围发生变化呢?
@luzemin: 事务A查询的数据加了间隙锁,然后间隙外的数据变化了,但是在A事务不会查询事务之外的数据,只查询本事务需要查询的数据,就算间隙外数据(也就是事务A查询范围之外的数据)变化了也不会产生幻读吧?
@yyyyyu: 幻读则是指一个事务在读取某个范围内的记录时,另外一个事务又在该范围内插入了新的记录,导致第一个事务再次读取该范围时,发现多了一些新的记录,就像发生了幻觉一样,这种现象被称为“幻读”。
幻读的概念本身就是说数据变化前后读取不一致,像幻觉。
你要是在数据变化之后不再次读取数据,因为就没读,那也不存在幻读。