SQL Server中的只读锁

时间:2010-12-13 10:22:03

标签: sql-server sql-server-2008 locking

我似乎在SQL Server 2008中遗漏了一些错误。这是我的方案:

  1. Begin tran。
  2. 从表A中读取以确保找到特定行。
  3. 在阅读时,在单行读取上放置一个只读锁。如果没有找到,请抛出错误。
  4. 插入表B,其中包括对表A的引用。
  5. 提交tran(释放锁定)。
  6. 由于各种设计限制,在这个特定的实例中,我无法创建一个关系来为我管理这个。所以我必须用代码来做。

    我不想XLOCK或UPDLOCK表A,因为我所处的事务只是从中读取,而不是写入。但是,显然我不想要任何其他内容来更新/删除引用的行。 所以我需要从外部角度看的只读锁

    我不希望任何幻像读取成为可能。我显然不希望有不同的行版本。

    一旦tran已经提交,就可以修改表A,因为触发器(删除后)将使表B中的引用为空。

    这就是我所拥有的:

    BEGIN TRAN
    -- test
    IF NOT EXISTS (
      SELECT  1
      FROM    Table1
      WITH    (HOLDLOCK, ROWLOCK)
      WHERE   (ID = @ID)
      ) {throw}
    
      {perform insert into Table2}
    COMMIT TRAN
    

1 个答案:

答案 0 :(得分:1)

在交易期间将交易隔离级别设置为REPEATABLE READ。在我看来,这也是使用锁定HINTS的首选,因为代码实现的清晰度会提高。

当您只阅读一行时,您无需担心范围插入到您的集合中,这是一个可重复阅读的警告。

我建议阅读本书Professional SQL Server 2008 Internals and Troubleshooting中的“锁定和锁存”一章。它包含SQL Server中可用的各种隔离级别的优秀解释,包括代码示例,以及描述每个数据异常场景的机制,例如Phantoms等。

免责声明:我不在这个职位的工资单上,但我有两份副本,一份是硬件,另一份是kindle版本,这就是我买两次的好处!