MSSQL:如果行不存在,HOLDLOCK 如何工作?

MSSQL: How does HOLDLOCK work if row does not exists?

我运行这个查询:

IF EXISTS(SELECT * FROM dbo.Foo WITH (UPDLOCK, HOLDLOCK) WHERE Col1 = @Col1 AND Col2 = @Col2)
...

假设 Col1 和 Col2 都不是主键并且查询不匹配任何行:

锁定是在哪个实体上? table 本身?

看起来如果没有相关索引,它会 RangeS-U 锁定所有聚集索引键,或者在堆的情况下,它会采用独占 table 锁。 EG

use tempdb
go
drop table if exists Foo
go

create table Foo(id int primary key /*nonclustered*/, Col1 int, Col2 int);
go
with q as
(
select row_number() over (order by (select null)) i
from sys.messages 
)
insert into foo(id,Col1,Col2) 
select top 10 i, i*10, i* 5 
from q


begin transaction

declare @Col1 int = 15
declare @col2 int = 5

SELECT * FROM dbo.Foo WITH (UPDLOCK, HOLDLOCK) 
WHERE Col1 = @Col1 AND Col2 = @Col2

select *
from sys.dm_tran_locks
where request_session_id = @@spid 

rollback