【问题标题】:Deadlock between 2 queries from 2 stored procedures来自 2 个存储过程的 2 个查询之间的死锁
【发布时间】:2017-08-16 19:51:42
【问题描述】:

我有一个奇怪的死锁问题,一直困扰着我。场景如下:

根据照片,第二个存储过程在第一次插入表中之前无法更新该锦标赛编号的数据。在这种情况下它怎么可能死锁,我怎么可能重现它并避免它?

谢谢。

第二张截图:

【问题讨论】:

  • 我们能看到 procs 吗?
  • 没有办法让我们用给出的信息 100% 回答这个问题,但我猜该图不包括链接表,并且这些表导致了死锁。另一个可能的原因是 SP2 正在更新多行并进行一次更新,但在等待下一次更新时没有释放表锁。
  • @AaronDietz - 更新,我添加了第二张照片。
  • @Hogan - 请看第二张照片。不,SP2 每次调用只更新一个锦标赛。
  • @Claudio -- 所以你有一个游览表和一个游览状态表。您是否在两个 SP 中都引用了这两个表?您是否以相同的顺序引用它们?在同一个TRANS?桌子上有触发器吗?触发器是否以相同的顺序触发。这些图表的问题是它们太简单了。我们需要查看死锁中的所有代码和/或日志信息,以了解发生这种情况的原因。此外,它可能只是一个缓慢的服务器。通常 SQL Server 会将一些缓慢的查询标记为死锁,因为它们只是缓慢未锁定。 WITH #NOLOCK 尽你所能,可能会有所帮助

标签: tsql stored-procedures deadlock sql-server-2016


【解决方案1】:

有关序言的主要问题,请参见 cmets。这里的问题是两个表(AB)以不同的顺序发生,所以它是这样发生的:

  1. SP1 完成并发布 id n1。
  2. SP2 使用 id n1 并锁定表 B
  3. SP1 以新编号开始并锁定表A。然后尝试锁定表 B 但 SP2 有它。
  4. SP2 现在尝试锁定表 A,但 SP1 拥有它。

死锁

注意:这基本上就是每个死锁的发生方式,只是围绕它的一些复杂的绒毛。这完全取决于您锁定表和释放它们的顺序。如果所有内容都以相同的顺序锁定和释放,则永远不会出现死锁。

【讨论】:

  • 它不起作用@Hogan :-( 我试过了,但是第一个 SP 只是插入了新的锦标赛号码而没有任何问题,即使在桌子上放置了锁并且 SP2 没有死锁.
  • @Claudio -- 什么不起作用?这听起来像是改变 SP2 上的顺序使它不会陷入僵局——这不是目标吗?
  • 是的,但我试图首先在开发环境中重现它,因为它不会死锁。它是无法复制的其中之一(即使使用 WAITFOR DELAY '00:00:10' 例如)?
  • @Claudio -- 很难重现,因为简单的等待并非在所有情况下都有效 -- 您必须对其计时,以便双方同时击中“中间”部分,然后一个在另一个之前到达第二个。所以你可以强制它,但你必须能够控制第 1 步和第 3 步以及它们之间的时间。 ——你能做到吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-01-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-15
  • 2013-07-04
相关资源
最近更新 更多