当查询条件为非主键字段时,为什么在SQLServer的更新锁(UPDLOCK)会锁表
大家能不能帮我看看,当查询条件为非主键字段时,为什么在SQLServer的更新锁(UPDLOCK)会整表锁定?
===========================================================
当我采用主键au_id列作为查询条件时,可以正常锁定查询的行:
begin tran
select * from authors with(updlock) where au_id=1
update authors set au_lname='aaa' where au_id=1
waitfor delay '00:00:30'
commit tran
上面语句中,我延时了30秒,在这30秒内:
1、另外打开第一个查询窗口,编写如下代码:(结果:
正常已锁定,不能更新)
update authors set au_lname='aaa' where au_id=1
2、另外打开第二个查询窗口,编写如下代码:(结果:
正常未锁定,可以更新):
update authors set au_lname='aaa' where au_id=1
=============================================================
当我采用非主键au_lname列作为查询条件时,则不能正常锁定查询的行:
begin tran
select * from authors with(updlock) where au_lname='White'
update authors set au_lname='bbb' where au_lname='White'
waitfor delay '00:00:30'
commit tran
上面语句中,我一样延时了30秒,在这30秒内:
1、另外打开第一个查询窗口,编写如下代码:(结果:
正常已锁定,不能更新)
update authors set au_lname='bbb' where au_lname='White'
2、另外打开第二个查询窗口,编写如下代码:(结果:
不正常已锁定,不能更新):
update authors set au_lname='bbb' where au_lname='Green'
------解决方案--------------------2、另外打开第二个查询窗口,编写如下代码:(结果:正常未锁定,可以更新):
update authors set au_lname='aaa' where au_id=1
例子应该是au_id=2之类的吧
-----------
准确的说不是主键的问题,而是聚集索引的缘故
数据的物理顺序是由聚集索引决定的,而且数据量少的话会精确锁定行
(一般数据量大的话都会引起锁升级)
而非聚集索引列应该是存储的聚集索引键值与对应列的数据,
所以非聚集索引锁定行的时候范围可能会大