SQL Server死锁图:请解释一下

Posted

技术标签:

【中文标题】SQL Server死锁图:请解释一下【英文标题】:SQL Server deadlock graph: please explain 【发布时间】:2017-01-25 23:10:01 【问题描述】:

我无法理解 Azure SQL Server V12 中的 deadlock_xml。这是图表(与底层 XML 一致):

因此,rhs 进程已发出更新锁,而 lhs 进程也需要在同一资源上获得更新锁,因此必须等待。

然后 rhs 进程请求对同一资源的排他锁,这显然是由于 lhs 进程的更新锁而被阻塞(为什么?因为它已经请求了一个??!)。

我的问题:

为什么rhs进程不能将U锁限制为X锁?

我试图从高层次上理解这一点,但是,这里有一些细节:

两个进程运行相同的 sp

sp 执行 upsert 操作:在不存在的地方插入(选择...);如果@@ROWCOUNT= 0 更新...

事务是可序列化的。

【问题讨论】:

【参考方案1】:

这两个操作都影响同一张表。您会在主键索引“PK_Product”上看到 Key Lock

我试着举一个简单的例子:

一个男人走进一个房间说:“我要拆掉这堵墙!”然后走出去拿他的工具。另一个人进来说:“我要粉刷这面墙!”然后走出去取颜色。现在两人都回来了,想开始工作。拆墙的人开始得早了一点。现在对于第二个人来说,等待是没有意义的。这些进程无法序列化。他等不及了,直到第一个完成。第一个人的工作改变了他工作的基础,使之成为不可能。

对您而言,这意味着:两个进程都说:“我们将更新此表,但我们首先检查某个条件”。由于INSERT 影响主键,第二个进程不能等待并稍后继续。这个进程只能被杀死并重新启动。

您可以查看MERGE-command,它允许您一次性执行 upsert。

【讨论】:

@Shungo 谢谢你的回答!我现在很清楚。我天真地期望锁定在逻辑而不是物理级别。与隔离级别“可序列化”合并确实是我的 upsert 问题的解决方案。不幸的是,我没有足够的代表来公开支持你的答案。

以上是关于SQL Server死锁图:请解释一下的主要内容,如果未能解决你的问题,请参考以下文章

SQL Server 上的死锁跟踪

了解sql server的死锁图

Sql server 死锁排查

SQL Server Profiler 中的死锁图显示同一集群键上的互锁

SQL Server死锁问题:事务(进程 ID x)与另一个进程被死锁在 锁 | 通信缓冲区资源上并且已被选作死锁牺牲品。请重新运行该事务。

sql server 死锁排查