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子句从表中选择数据以重新指定范围
  • 等等
  • 在第二个连接中,我将数据插入表中,其值与第一个连接中的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
    添加到您的测试表中,然后重试。谢谢,您是对的。添加几行后,它似乎可以工作。