sql-server - Parallel merge strategy without deadlock
问题描述
Using SQL Server 2016, I wish to merge data from a SourceTable
to a DestinationTable
with a simple procedure containing a simple insert/update/delete on the same table.
The SourceTable
is filled by several different applications, and they call the MergeOrders
stored procedure to merge their uploaded rows from SourceTable
into DestinationTable
.
There can be several instances of MergeOrders
stored procedure running in parallel.
I get a lot of lock, but that's normal, the issue is that sometimes I get "RowGroup deadlocks", which I cannot afford.
What is the best way to execute such merge operation in this parallel environment.
I am thinking about TABLOCK or SERIALIZABLE hints, or maybe application locks to serialize the access, but interested if there is better way.
解决方案
应用程序锁将序列化尝试运行此过程的会话。它应该如下所示:
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。并且您希望显式释放应用程序锁,以防在长时间运行的事务的上下文中调用此过程。最后将锁的主体设置为,dbo
以便非 dbo 用户无法获得冲突锁。这也需要运行该过程execute as owner
,因为应用程序用户通常不会这样做dbo
。
推荐阅读
- linux - 系统更新后 SDDM 损坏
- node.js - 如何在一个命令中使用 mongoose 检索配置文件和用户模式?
- c# - 为什么当我将添加的实体状态更改为已修改时会发生 ConcurrencyException
- file - 如何仅提取超过 9000 万行的“.txt”文件中的电子邮件
- c# - 角色移动、加速 C# Unity
- java - java.lang.module.ResolutionException
- python - Python中离散变量的逆方法
- office365 - PowersShell 连接到 Microsoft Office 365 Outlook 服务器失败
- html - 使用 XMLStarlet 解析 html 时命名空间的担忧
- node.js - 节点用 csrf 表达静态