我在SQL Server中遇到了一个我无法解决的死锁问题。
基本上我有很多并发连接(来自许多机器)执行事务,他们首先删除一系列条目,然后使用批量插入重新插入相同范围内的条目。
基本上,交易看起来像这样
BEGIN TRANSACTION T1
DELETE FROM [TableName] WITH( XLOCK HOLDLOCK ) WHERE [Id]=@Id AND [SubId]=@SubId
INSERT BULK [TableName] (
[Id] Int
, [SubId] Int
, [Text] VarChar(max) COLLATE SQL_Latin1_General_CP1_CI_AS
) WITH(CHECK_CONSTRAINTS, FIRE_TRIGGERS)
COMMIT TRANSACTION T1
批量插入仅在同一事务中插入与删除的Id和SubId匹配的项目。此外,这些Id和SubId条目不应重叠。
当我有足够的此表单并发事务时,我开始看到这些语句之间存在大量死锁。
我添加了锁定提示XLOCK HOLDLOCK以尝试解决问题,但它们似乎没有帮助。
此错误的规范死锁图表显示:
连接1:
连接2:
我需要做些什么才能确保不会发生这些死锁。
我一直在研究RangeX-X锁,我不确定我是否完全理解这些锁的发生情况。我有没有选择锁定整个表格的选项?
答案 0 :(得分:2)
继Sam Samffron的回答之后:
答案 1 :(得分:1)
如果没有索引/表大小等列表,很难给出准确的答案,但请记住,SQL无法在同一实例中获取多个锁。它会在一次抓取一个锁,如果另一个连接已经拥有锁并且它对第一个事务需要的东西保持锁定,那么kaboom就会出现死锁。
在这个特定的例子中,您可以做一些事情: