1

我有几个 MERGE 语句,我在 ADO.NET 代码中的事务内执行。

第一个表的 ID 将在插入表时自动分配。第二个表确实有一个外键约束,这就是为什么我在我的插入语句中有这个选择。

匹配实际上是基于一些自然键,因为代理键没有暴露在应用程序之外。

MERGE 语句看起来像这样。

merge MyTable with (rowlock, updlock) as t
using #someTempTable as s
on (t.[VarcharColumn] = s.[VarcharColumn])
when not matched by target
   then insert (...)
   values (...)
when matched
   then update set ... ;

merge SecondTable with (rowlock, updlock) as t
using #otherTempTable as s
on (t.[] = s.[])
when not matched by target
   then insert ([OtherColumn],[MyTable_Id])
   values (s.[OtherColumn], 
          (select Id from MyTable where MyTable.[VarcharColumn] = s.[VarcharColumn]))
when matched
   then update set ... ;

在多个并行事务中运行这些语句时,表上会发生死锁。通过添加行锁提示,我能够减少插入时的一些死锁,但更新语句总是会导致问题。

我不是数据库优化方面的专家,很难找出发生了什么以及如何改进它。有人对这些问题有一些专业意见吗?

4

1 回答 1

0

将您的锁定提示修改为WITH (HOLDLOCK). 这将导致 MERGE 语句在整个语句中保持对受影响行的锁定,并且应该消除死锁。

于 2014-08-20T22:46:59.517 回答