无死锁的并行合并策略

Parallel merge strategy without deadlock

使用 SQL Server 2016,我希望通过一个包含简单 insert/update/delete 的简单过程将数据从 SourceTable 合并到 DestinationTable table.

SourceTable 由几个不同的应用程序填充,他们调用 MergeOrders 存储过程将他们上传的行从 SourceTable 合并到 DestinationTable

MergeOrders 存储过程 运行 可以有多个并行实例。

我得到很多锁,但这是正常的,问题是有时我得到 "RowGroup deadlocks",这是我负担不起的。

在此并行环境中执行此类合并操作的最佳方式是什么。

我正在考虑 TABLOCK 或 SERIALIZABLE 提示,或者应用程序锁来序列化访问,但如果有更好的方法我很感兴趣。

应用锁将序列化尝试运行此过程的会话。它应该是这样的:

create or alter procedure ProcWithAppLock 
with execute as owner
as
begin
  set xact_abort on;
  set nocount on;
  begin transaction;
  declare @lockName nvarchar(255) = object_name(@@procid) + '-applock';
  exec sp_getapplock @lockName,'Exclusive','Transaction',null,'dbo';


  --do stuff
  waitfor delay '00:00:10';
  select getdate() dt, object_name(@@procid);

  exec sp_releaseapplock @lockName, 'Transaction', 'dbo';
  commit transaction;
end

此模板中有一些细微之处。首先它没有 catch 块,并且在发生错误时依赖 xact_abort 来释放 applock。并且您希望明确释放应用程序锁,以防在较长 运行ning 事务的上下文中调用此过程。最后,锁的主体设置为 dbo,这样非 dbo 用户就无法获取冲突锁。这也要求过程是 运行 和 execute as owner,因为应用程序用户通常不会是 dbo.