【问题标题】:How to enforce key-range locking如何强制执行键范围锁定
【发布时间】:2015-09-28 15:54:33
【问题描述】:

我有一张由以下字段组成的带有CLUSTERED PRIMARY KEY 的表格:

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

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

我环顾四周,发现SERIALIZABLE ISOLATION LEVEL 允许按键范围锁定,但我尝试的每一种方法都失败了。

我设置了 2 个 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

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

那么这些按键范围锁是如何工作的? 有没有可能得到我想要的东西?

我尝试过的其他事情:

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

【问题讨论】:

  • 您是否考虑过分区以确保每个 Group 实际上是一个单独的表?
  • @MatBailie 这可能是一回事,我从来没有想过。我只需要对表进行分区而不需要其他任何东西吗?
  • 恐怕你需要自己调查一下。多年未使用 SQL-Server。

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


【解决方案1】:

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

【讨论】:

  • 我的目标是锁定我正在更新的行。如果 UPDLOCK 是我要找的东西,我明天试试。
猜你喜欢
  • 2011-05-07
  • 2012-01-22
  • 2011-09-26
  • 2013-04-19
  • 2021-07-10
  • 1970-01-01
  • 2011-02-06
相关资源
最近更新 更多