2015-09-28 35 views
0

我有一个表与以下领域取得一个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个管理工作室翼片,每一个具有相同的代码,只是不同组的值(在本例中AB在其它标签)

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用于禁用锁升级的跟踪标志。也无法工作(它实际上禁用锁升级到表级别,但这不会改变任何东西)。
  • 寻找离彼此很远的团体。 (也许有一些共同的页面...我不知道)
+0

您是否考虑过分区以确保每个组实际上都是一个单独的表? – MatBailie

+0

@MatBailie这可能是一件事,我从来没有想过这件事。我只需要分割桌子而没有别的? – mordack550

+0

你需要自己去看看,我很害怕。多年以来未使用SQL-Server。 – MatBailie

回答

0

我相信你的问题是由于这个事实,你的钥匙是一个复合钥匙,包括3个不同的领域,你只能选择一个那些领域。如果您确实想阻止另一个会话更新您当前正在阅读的数据,那么请在您的交易问题中更新UPDLOCK。这会阻止其他会话读取这些记录,直到您的事务被提交或回滚。这也不具有ROWLOCK所具有的令人讨厌的效果,它经常会升级到TABLE LOCK,从而导致DEADLOCKS。 UPDLOCK将导致BLOCKING而不是DEADLOCKING。

+0

我的目标是*只*锁定行我正在更新。如果UPDLOCK是我正在寻找的,我会明天再试。 – mordack550