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
我运行这个查询:
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