如何重构这个死锁问题?

时间:2015-01-31 20:38:16

标签: sql-server tsql sql-server-2005 deadlock

我在很短的时间内多次遇到死锁问题synchronizing。通过同步我的意思是做以下事情:

  1. 将要同步的数据插入临时表
  2. 更新目标表中的现有记录
  3. 将新记录插入目标表
  4. 删除某些情况下不在同步表中的记录 情况
  5. 放下临时表
  6. 对于INSERTDELETE语句,我使用的LEFT JOIN类似于:

    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;
    

    死锁图表报告destination_table的主键位于独占锁定下。我假设上面的查询导致表或页锁而不是行锁。我该如何确认?

    我可以使用INEXISTEXCEPT命令重写上述查询。有没有其他方法来重构代码?使用任何这些命令重构是否可以避免死锁问题?哪一个最好?我假设EXCEPT

1 个答案:

答案 0 :(得分:0)

在正常情况下,我可以很好地执行方案。以下是我创建的测试脚本。你在尝试别的吗?

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