如何实施键范围锁定

时间:2015-09-28 15:54:33

标签: sql sql-server transactions locking sql-server-2014

我有一个由CLUSTERED PRIMARY KEY创建的表格,其中包含以下字段:

| Group |  ID  | Other non-key fields...
|   A   |   1  |   foo
|   A   |   2  |   bar
|   B   |   1  |   so

我总是按特定的组值(WHERE Group = @Something)访问此表格。 我知道只有一个客户端可以访问每个组(因为它创建它,并且没有其他客户端知道存在哪些其他组)所以我的问题是:是否有办法保证对表的并发访问,因为表是始终由组列访问,只有一个客户端在一个组上工作?

我环顾四周,看到SERIALIZABLE ISOLATION LEVEL允许键范围锁定,但我尝试的每一种方式都会失败。

我设置了两个Management Studio标签,每个标签都有相同的代码,只有不同的组值(本例中为A,另一个标签为B

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
BEGIN TRANSACTION
SELECT * FROM MyTable
WHERE Group = 'A'
GO
UPDATE MyTable
SET AField = 'something'
WHERE Group = 'A'

--ROLLBACK

事实是我运行的第一个事务锁定了所有事务,并阻止另一个事务甚至从表中读取数据。

那么Key-Range Locks是如何工作的? 是否有可能获得我所要求的东西?

我试过的其他事情:

  • ROWLOCK暗示。在MSDN页面上也不起作用,我发现ROWLOCK提示不会阻止锁升级到表级。
  • 1211跟踪标志,用于禁用锁定升级。也不起作用(它实际上禁止锁升级到表级别,但这不会改变任何东西)。
  • 寻找彼此相距甚远的群体。 (也许有一些共同的页面......我不知道)

1 个答案:

答案 0 :(得分:0)

我认为您的问题是由于您的密钥是包含3个不同字段的复合密钥而您只选择其中一个字段。如果您确实希望阻止其他会话更新您当前正在阅读的数据,那么在您的交易中会发出 UPDLOCK 。这将阻止其他会话读取这些记录,直到您的事务被提交或回滚。这也没有ROWLOCK所具有的令人讨厌的效果,这通常会升级到TABLE LOCK,导致DEADLOCKS。 UPDLOCK将导致BLOCKING而不是DEADLOCKING。