可以在添加主键标识列解决死锁的问题?(Can adding a primary key identi

2019-06-24 18:09发布

我在SQL Server中的表,它是CRUD-ED同时在不同的会话同时运行一个存储过程:

|----------------|---------|
| <some columns> | JobGUID |
|----------------|---------|

该过程如下:

  1. 生成一个GUID。
  2. 插入一些记录到共享表。如上所述,与来自步骤1中的GUID将它们标记。
  3. 步骤2执行上的所有记录一些更新。
  4. 从步骤3作为SP输出选择的记录。

每一个选择/插入/更新/存储过程删除语句具有WHERE JobGUID = @jobGUID条款,所以程序仅适用于已插在步骤2中。然而记录,有时在同一个存储过程中并行运行在不同的连接,发生在共享表死锁。 下面是从SQL Server Profiler中的死锁图形:

锁升级不会发生。 我尝试添加(UPDLOCK, ROWLOCK)锁提示所有DML语句和/或包装过程的主体在交易中使用不同的隔离级别,但它并没有帮助。 仍然在共享的表相同的RID锁。

在那之后,我发现共享表没有主键/标识列。 而一旦我说了,死锁似乎消失了:

alter table <SharedTable> add ID int not null identity(1, 1) primary key clustered

当我删除主键列,死锁回来了。 当我添加回去,我不能再重现僵局。

所以,问题是,是一个主键标识列真正能够解决死锁或者是它只是一个巧合吗?

更新:作为@Catcall建议,我已经尝试创建现有列的自然聚集主键(无添加标识列),但还是抓住了相同的僵局(当然,这一次是一键锁定,而不是RID锁)。

Answer 1:

最好的资源(仍然)死锁分辨率是在这里: http://blogs.msdn.com/b/bartd/archive/2006/09/09/deadlock-troubleshooting_2c00_-part-1.aspx 。

铂#4说:

通过运行数据库引擎优化顾问参与了僵局查询。 扑通一声在Management Studio中的查询窗口查询,更改数据库上下文正确的数据库,用鼠标右键单击该查询文本,然后选择“分析查询在DTA”。 不要跳过此步骤; 以上我们看到的都是解决问题的僵局一半仅仅通过使查询的一个运行更迅速,更小的占地面积锁添加适当的索引。 如果DTA建议索引(它会说“估计改进:%”),创建它们和监控,看是否僵局仍然存在。 您可以选择从操作下拉菜单中选择“应用建议”,立即创建索引,或保存CREATE INDEX作为脚本在维护期间创建它们的命令。 一定要调整每个单独的查询。

我知道这并不“回答”的问题为什么必然,但它确实表明,添加索引可以改变的方式执行,使任一锁定足迹较小或执行时间快,可减少显著僵局的机会。



Answer 2:

最近我已经看到了这个帖子,根据上述资料,我希望这篇文章可以帮助你,

http://databaseusergroup.blogspot.com/2013/10/deadlocked-on-sql-server.html



文章来源: Can adding a primary key identity column solve deadlock issues?