我有以下过程(SQL Server 2008 R2):
create procedure usp_SaveCompanyUserData
@companyId bigint,
@userId bigint,
@dataTable tt_CoUserdata readonly
as
begin
set nocount, xact_abort on;
merge CompanyUser with (holdlock) as r
using (
select
@companyId as CompanyId,
@userId as UserId,
MyKey,
MyValue
from @dataTable) as newData
on r.CompanyId = newData.CompanyId
and r.UserId = newData.UserId
and r.MyKey = newData.MyKey
when not matched then
insert (CompanyId, UserId, MyKey, MyValue) values
(@companyId, @userId, newData.MyKey, newData.MyValue);
end;
Run Code Online (Sandbox Code Playgroud)
CompanyId、UserId、MyKey 构成目标表的组合键。CompanyId 是父表的外键。此外,还有一个非聚集索引CompanyId asc, UserId asc。
它是从许多不同的线程调用的,我一直在调用相同语句的不同进程之间出现死锁。我的理解是“with (holdlock)”对于防止插入/更新竞争条件错误是必要的。
我假设两个不同的线程在验证约束时以不同的顺序锁定行(或页面),因此是死锁。
这是一个正确的假设吗? …