Sql server 如何重构这个死锁问题?

Sql server 如何重构这个死锁问题?,sql-server,tsql,sql-server-2005,deadlock,Sql Server,Tsql,Sql Server 2005,Deadlock,我在短时间内多次同步表时遇到了死锁问题。同步是指执行以下操作: 将要同步的数据插入临时表 更新目标表中的现有记录 将新记录插入目标表 删除不在特定条件下的同步表中的记录 情况 下降温度表 对于INSERT和DELETE语句,我使用类似于以下内容的左连接: INSERT INTO destination_table (fk1, fk2, val1) FROM #tmp LEFT JOIN destination_table dt ON dt.fk1 = #tmp.fk1 AND dt.fk2

我在短时间内多次同步表时遇到了死锁问题。同步是指执行以下操作:

将要同步的数据插入临时表 更新目标表中的现有记录 将新记录插入目标表 删除不在特定条件下的同步表中的记录 情况 下降温度表 对于INSERT和DELETE语句,我使用类似于以下内容的左连接:

INSERT INTO destination_table (fk1, fk2, val1)
FROM #tmp
LEFT JOIN destination_table dt ON dt.fk1 = #tmp.fk1
   AND dt.fk2 = #temp.fk2
WHERE dt.pk IS NULL;
死锁图报告目标_表的主键处于独占锁下。我假设上面的查询导致的是表锁或页锁,而不是行锁。我如何确认这一点


我可以用IN、EXIST或EXCEPT命令重写上述查询。有没有其他重构代码的方法?使用这些命令中的任何一个进行重构会避免死锁问题吗?哪一个最好?我假设除了。

在正常情况下,我可以很好地执行场景。下面是我创建的测试脚本。你在试别的吗

drop table #destination_table
drop table #tmp

Declare @x int=0

create table #tmp(fk1 int, fk2 int, val int)

set @x=2

while (@x<1000)
begin
    insert into #tmp
    select @x,@x,100
    set @x=@x+3
end

create table #destination_table(fk1 int, fk2 int, val int)
while (@x<1000)
begin
    insert into #destination_table
    select @x,@x,100
    set @x=@x+1
end



INSERT INTO #destination_table (fk1, fk2, val)
select t.*
FROM #tmp t
LEFT JOIN #destination_table dt ON dt.fk1 = t.fk1
     AND dt.fk2 = t.fk2
WHERE dt.fk1 IS NULL

这些都是在交易中完成的吗?您使用的是什么事务隔离级别?是否有其他活动使用目标表?因为您的测试只使用从单个连接访问的本地临时表,所以创建死锁的可能性较小。