【问题标题】:Read-only lock in SQL ServerSQL Server 中的只读锁
【发布时间】:2010-12-13 10:22:02
【问题描述】:

我似乎在 SQL Server 2008 中遗漏了一些锁。这是我的场景:

  1. 开始翻译。
  2. 从表 A 中读取以确保找到特定行。
  3. 读取时,对单行读取设置只读锁。如果没有找到,抛出错误。
  4. 插入表 B,其中包括对表 A 的引用。
  5. 提交 tran(释放锁)。

由于各种设计限制,在这种特殊情况下,我无法创建关系来为我管理它。所以我必须用代码来做。

我不想 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

【问题讨论】:

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


    【解决方案1】:

    在事务期间将事务隔离级别设置为 REPEATABLE READ。在我看来,这也比使用锁定 HINTS 更可取,因为您的代码实现更加清晰。

    由于您只读取单行,因此您无需担心向集合中插入范围,这是 REPEATABLE READ 的警告。

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

    免责声明:我不在此书的工资单上,但我确实有两本,一本硬版,另一本 Kindle 版,我买了两次真是太好了!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多