可序列化事务隔离锁

5
我已经为事务设置了可序列化的事务隔离锁,但我观察到一些结果与预期不符。
我的查询是:
update tabl1 set col2 = 10 where col1 > 10 and col1 < 20

这里的col1是主键。具有值为10、11、12……19、20的col1行将被锁定,以进行更新/插入操作。在where条件中,我已经给出了col1>10和col1<20的条件,但仍然会锁定col1=10和col1=20的行。

如果我只给出

update tabl1 set col2 = 10 where col1 => 10 and col1 <= 20

当col2的值在9到21之间时,相应的行将被锁定。那么为什么col1的值为9和21的行也会被锁定呢?

对于以下查询,整个表都会被锁定。这里col3是非主键列。如果where条件中的列不是主键,我不能设置锁吗?

update tabl1 set col2 = 10 where col3 > 10 and col3 < 20
1个回答

4

对于键范围锁,SQL Server必须使用索引来满足范围条件,因此针对您的最后一个查询,您需要在col3上创建一个索引(如果计划没有使用它,则可能需要查询提示来强制使用它)。

此外,它不仅锁定WHERE子句中特定的范围,而是锁定键。对键进行范围锁定可保护该键向下至下一个键的范围,因此将被阻止的确切范围取决于索引中存在哪些键。

更多详细信息/链接请参见我的答案


但是应该使用哪个索引?聚集索引还是非聚集索引? - wincoding
@wincoding - 只要它使用该索引解析WHERE,SQL Server可以在任何一个上采取关键范围锁定并没有区别。 - Martin Smith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接