这是一个关于如何锁定值范围的一般性问题(没有其他问题!)当它们还没有在桌子上存在的时候。问题的触发因素是,我想做“插入(如果不存在)”,我不想使用MERGE,因为我需要支持Server 2005。
在第一方面,我:
begin transaction(SERIALIZABLE, ROWLOCK) + where子句从表中选择数据以重新分配范围在第二个连接中,我用不匹配第一个连接中的where子句的值向表插入数据。
我希望第二个连接不会受到第一个连接的影响,但它只有在提交(或回滚)第一个连接的事务之后才会结束。
我遗漏了什么?
这是我的测试代码:
首先创建这个表:
CREATE TABLE test
(
VALUE nvarchar(100)
)其次,打开新的查询窗口并执行以下操作:
BEGIN TRANSACTION;
SELECT *
FROM test WITH (SERIALIZABLE,ROWLOCK)
WHERE value = N'a';第三,打开另一个新的查询窗口并执行以下操作:
INSERT INTO test VALUES (N'b');注意,第二个查询直到第一个窗口中的事务结束为止
发布于 2011-12-04 10:47:40
您在VALUE上缺少一个索引。
没有这一点,Server就没有任何东西可以打开键范围锁,并将锁定整个表以锁定范围。
然而,即使添加了索引,您仍然会遇到问题中的方案阻塞。RangeS-S锁不会锁定查询中给定的特定范围。相反,它会锁定所选范围的任一键之间的范围。
当没有这样的键,两边的距离锁延伸到无穷大。您需要在a和b (例如aa)之间添加一个值,以防止在测试中发生这种情况,并阻止b的插入。
有关此问题的更多信息,请参阅本文中的附加附录:射程锁。
https://stackoverflow.com/questions/8374760
复制相似问题