SQL死锁删除然后批量插入

我有一个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:

  • 在PK_TableName上保存RangeX-X
  • 在表格上保存IX页面锁定
  • 请求表格上的X页面锁定
  • 连接2:

  • 在表格上保存IX页面锁定
  • 请求RangeX-X锁定在表上
  • 我需要做些什么才能确保这些僵局不会发生。

    我一直在阅读RangeX-X锁,我不确定我完全理解这些。 我有没有任何选项可以锁定整个表格?


    继萨姆萨夫龙的回答之后:

  • 如果@ ID7 @ SubID是distinc,请考虑READPAST提示跳过所有保留的锁
  • 考虑使用SERIALIZABLE并移除XLOCK,HOLDLOCK
  • 对批量插入使用单独的临时表,然后从中复制

  • 它很难给你一个准确的答案,没有索引/表大小列表等,但请记住,SQL不能在同一个实例中获取多个锁。 它会一次抓取一个锁,并且如果另一个连接已经拥有该锁并且它对第一个事务需要的某个锁具有锁定,那么kaboom会导致死锁。

    在这个特定的例子中,你可以做几件事情:

  • 确保(Id,SubId)上有一个索引,这样SQL就能够为要删除的数据获取一个范围锁。
  • 如果死锁变得罕见,请重试您的死锁。
  • 你可以用sledghammer来解决这个问题,并使用一个TA​​BLOCKX,它不会造成死锁
  • 使用跟踪标记1204获得准确的死锁分析http://support.microsoft.com/kb/832524(关于实际死锁的更多信息越容易解决)
  • 链接地址: http://www.djcxy.com/p/32859.html

    上一篇: SQL deadlock on delete then bulk insert

    下一篇: SQLServer deadlock