2015-01-31 70 views
0

我在短时间内多次遇到死锁问题synchronizing表。通过同步我的意思是做了以下内容:如何重构这个死锁问题?

  1. 插入数据被同步到一个临时表
  2. 更新的目标表中已有的记录
  3. 新记录插入到目标表
  4. 删除不记录在某些特定 情况下,同步表
  5. 删除临时表

对于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

+0

这是否都是在交易中完成的?您使用的是什么事务隔离级别?是否有使用目的地表的其他活动? – HABO 2015-01-31 21:13:49

回答

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 @[email protected]+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 @[email protected]+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 
+0

由于您的测试只使用从单个连接访问的本地临时表,因此较小可能会造成死锁。 – HABO 2015-02-01 14:07:51