如何在SQLServer中强制索引约束上使用键锁

sqougxex  于 2021-08-09  发布在  Java
关注(0)|答案(1)|浏览(362)

我正在处理一个死锁问题,它只发生在大量数据的情况下。在获取sqlsentry日志时,我可以看到锁是聚集索引上的keylock( pk_tab12 )在标识列上 TAB_ID 在sp的下线中。。。

DELETE Mytable
OUTPUT deleted.field1, deleted.field2 INTO @temptabledeclaredbeforequery
WHERE TAB_ID = tabID

错误
“错误:1205,severity:13,state:51 in 第25行的proc sp\u myproc:
消息:(进程id 103)在另一进程的锁资源上被死锁,并被选为死锁受害者。
当我看到执行计划时,它没有显示这个索引的任何问题。不过,我计划通过更改为非聚集索引来修复它。我想知道的是,如何在dev环境中复制/强制死锁,以便检查我的修复是否有效?
注:我提供的信息是一个例子,因为我不能提供实际的信息。对不起的!

w6mmgewl

w6mmgewl1#

根据所提供的信息,我不希望此查询出现死锁,但它可能会与其他并发查询死锁。
死锁很难在高并发性工作负载中可靠地重新生成,但我在不同的ssms查询窗口中运行了与死锁相关的查询,并与执行同步,取得了一些成功 sp_getapplock 所以它们几乎同时运行。下面是这种技术的一个例子:
获取会话1上的独占锁以同步执行:

EXEC sp_getapplock @Resource = N'deadlock-synch', @LockMode = 'Exclusive', @LockOwner = 'Session';
GO

在会话2上执行查询1,等待释放锁:

EXEC sp_getapplock @Resource = N'deadlock-synch', @LockMode = 'Shared', @LockOwner = 'Session';
GO
--query 1 involved in deadlock
DELETE Mytable
OUTPUT 
deleted.field1
deleted.field2
INTO @temptabledeclaredbeforequery
where TAB_ID = tabID
GO
EXEC sp_releaseapplock @Resource = N'deadlock-synch', @LockOwner = 'Session';
GO

在会话3上执行查询2,等待释放锁:

EXEC sp_getapplock @Resource = N'deadlock-synch', @LockMode = 'Shared', @LockOwner = 'Session';
GO
--query 2 involved in deadlock
SELECT *
FROM MyTable
JOIN YourTable ON YourTable.Column1 = MyTable.Column1;
GO
EXEC sp_releaseapplock @Resource = N'deadlock-synch', @LockOwner = 'Session';
GO

最后,释放会话1上的独占锁以开始执行:

EXEC sp_releaseapplock @Resource = N'deadlock-synch', @LockOwner = 'Session';
GO

相关问题