所述文档的状态,该RangeI-N锁(插入范围,空资源锁;插入新钥匙插入的索引之前用于测试范围)是用本身兼容(参见兼容性矩阵),因此,即使一个事务已获得的RangeI -N lock on特定键另一个事务也可以获得这样的锁。
在下面,它说
在事务中插入值时,在执行插入操作的事务期间不必锁定值落入的范围。锁定插入的键值直到事务结束就足以保持可序列化性。例如,给定这个 INSERT 语句:
INSERT mytable VALUES ('Dan');
RangeI-N 模式键范围锁放置在与名称 David 相对应的索引条目上以测试范围。如果锁定被授予,则插入 Dan 并对值 Dan 放置一个排它 (X) 锁。RangeI-N 模式键范围锁仅在测试范围时才需要,在执行插入操作的事务期间不会保持。其他事务可以在插入值 Dan 之前或之后插入或删除值。但是,任何尝试读取、插入或删除值 Dan 的事务都将被锁定,直到插入事务提交或回滚。
引用另一个来源- Microsoft SQL Server 2008 Internals: Transactions and Concurrency:
例如,当 SQL Server 尝试使用 Serializable 隔离将会话中的键之间的范围插入时,将获取 RangeIn-Null 锁。这种类型的锁并不常见,因为它通常非常短暂。直到找到正确的插入位置,它才会被持有,然后该锁被转换为 X 锁。
我的理解是这种类型的锁是在识别新插入的钥匙应该放置的范围的过程中(我假设这就是“测试范围”的意思)。发生这种情况后,锁被释放,新的钥匙被插入,并在其上放置一个 X 锁。
但是我不明白为什么说两个 RangeI-N 锁是相互兼容的。如果事务 A 和 B 都在同一个键上放置 RangeI-N 锁,因为他们都想在范围中插入一个新键并且事务 A 先执行插入,那么由 B 确定的键插入位置可能已经不正确,因为范围发生了变化(A 在那里插入了一个新值)。有人能解释一下吗?