Sql Server忽略rowlock提示

Ams*_*taf 5 sql-server locking serializable

这是关于如何在表中不存在时锁定值范围(以及其他任何内容!)的一般问题.问题的触发器是我想要"插入如果不存在",我不想使用MERGE因为我需要支持SQL Server 2005.

在第一次连接中我:

  1. begin transaction
  2. 使用(SERIALIZABLE, ROWLOCK)+ where子句从表中选择数据以重新指定范围
  3. 等待...

在第二个连接中,我将数据插入到表中,其值与第一个连接中的where子句匹配

我希望第二个连接不会受到第一个连接的影响,但只有在我提交(或回滚)第一个连接的事务后才会完成.

我错过了什么?

这是我的测试代码:

首先创建此表:

CREATE TABLE test
(
    VALUE nvarchar(100)
)
Run Code Online (Sandbox Code Playgroud)

二,打开新的查询窗口sql server managements studio并执行以下命令:

BEGIN TRANSACTION;
SELECT *
FROM  test WITH (SERIALIZABLE,ROWLOCK)
WHERE value = N'a';
Run Code Online (Sandbox Code Playgroud)

第三,打开另一个新的查询窗口并执行以下操作:

INSERT INTO test VALUES (N'b');
Run Code Online (Sandbox Code Playgroud)

请注意,在第一个窗口中的事务结束之前,第二个查询不会结束

Mar*_*ith 8

你错过了一个索引VALUE.

如果没有这个,SQL Server就无法锁定密钥范围并锁定整个表以锁定范围.

即使添加了索引,您仍然会遇到问题中的方案阻塞.该RangeS-S锁不锁在查询中给出的具体范围.相反,它会锁定所选范围任一侧的键之间的范围.

当任何一侧没有这样的键时,范围锁定延伸到无限远.您需要在ab(例如aa)之间添加一个值,以防止在测试中发生这种情况并b阻止插入.

有关此内容的更多信息,请参阅本文中的附加附录:范围锁定.