Sql server Sql Server忽略行锁提示
这是一个关于在表中还不存在值的情况下如何锁定值范围(而不是其他!)的一般问题。引发这个问题的原因是我想执行“如果不存在则插入”,我不想使用Sql server Sql Server忽略行锁提示,sql-server,locking,serializable,Sql Server,Locking,Serializable,这是一个关于在表中还不存在值的情况下如何锁定值范围(而不是其他!)的一般问题。引发这个问题的原因是我想执行“如果不存在则插入”,我不想使用MERGE,因为我需要支持SQL Server 2005 在第一个方面,我: 开始交易 使用(SERIALIZABLE,ROWLOCK)+where子句从表中选择数据以重新指定范围 等等 在第二个连接中,我将数据插入表中,其值与第一个连接中的where子句不匹配 我希望第二个连接不会受到第一个连接的影响,但它只有在我提交(或回滚)第一个连接的事务后才能完成 我
MERGE
,因为我需要支持SQL Server 2005
在第一个方面,我:
开始交易
(SERIALIZABLE,ROWLOCK)
+where子句从表中选择数据以重新指定范围CREATE TABLE test
(
VALUE nvarchar(100)
)
其次,打开新的查询窗口sql server managements studio并执行以下操作:
BEGIN TRANSACTION;
SELECT *
FROM test WITH (SERIALIZABLE,ROWLOCK)
WHERE value = N'a';
INSERT INTO test VALUES (N'b');
第三,打开另一个新的查询窗口并执行以下操作:
BEGIN TRANSACTION;
SELECT *
FROM test WITH (SERIALIZABLE,ROWLOCK)
WHERE value = N'a';
INSERT INTO test VALUES (N'b');
请注意,直到第一个窗口中的事务结束,第二个查询才结束。您缺少
值的索引
如果没有这一点,SQL Server就没有什么可承担的,它将锁定整个表以锁定范围
即使添加了索引,您仍然会遇到问题中场景的阻塞。RangeS-S
锁不会锁定查询中给定的特定范围。相反,它会锁定选定范围两侧的关键点之间的范围
当两边都没有这样的钥匙时,范围锁会无限延伸。您需要在a
和b
(例如aa
)之间添加一个值,以防止在测试中发生这种情况,并阻止插入b
有关这方面的详细信息,请参阅本文中的。(:谢谢Martin,但没有帮助。我尝试添加索引(尝试了聚集索引和非聚集索引):“创建聚集索引ix_测试值(值)”它仍然是锁定选择值='a'仍然锁定插入值'b'。也许我错过了另一件事?10x@Amstaf-范围锁定锁定所选范围任意一侧的键之间的范围,因此当您针对空表执行此操作时,锁定的范围仍然是整个索引。请尝试添加两行,例如1
和AA
添加到您的测试表中,然后重试。谢谢,您是对的。添加几行后,它似乎可以工作。