【问题标题】:Suggestion to handle Deadlock处理死锁的建议
【发布时间】:2014-02-04 22:32:32
【问题描述】:

大约有 6 个程序在内部调用以从事务表中获取数据并对检索到的数据进行聚合,格式化为 XML,然后每小时发送电子邮件。

在此过程中,许多登录完成,日志也以 HTML 格式的电子邮件发送(在同一封电子邮件中)。有一个过程发生死锁,电子邮件的一部分总是丢失,或者我们发生死锁(LOGS)。因此,为了处理,我尝试在该特定过程中使用 READ_COMMITTED_SNAPSHOT。任何人都可以建议这是否对他们有用,否则这是处理这种死锁的最佳方法。

我可以通过检查输出是否为 Null 在内部重试该特定过程。

我不能让其他进程失败,因为这是一个事务。但我需要 HTML 来显示所有信息,而不会丢失正文中的任何内容。

编辑:这种情况很少发生。但是现在频率每天都在增加。我无法理解,因为该过程只是试图从事务表中读取并进行一些计算并将其格式化为 XML,而另一个事务是写入事务表。那么 WRITE 如何影响 READ

【问题讨论】:

  • 删除了 SQL Server 2008/2012 标签。

标签: sql sql-server deadlock


【解决方案1】:

您需要修复死锁才能解决此问题。

死锁发生在一个进程拥有另一个进程所需的资源以继续进行时,反之亦然。当您有两个进程以不同的顺序获取同一组资源时,您将遇到死锁。例如,如果进程 P1 按以下顺序获取资源:

  1. 资源 A
  2. 资源 B

而一个竞争进程 P2 以不同的顺序需要相同的资源:

  1. 资源 B
  2. 资源 A

    • P1 启动并获得对资源 A 的独占访问权。
    • P2 启动并获得对资源 B 的独占访问权。

为了让每个人都能继续,P1 需要访问资源 B,而 P2 需要访问资源 A。

两者都无法获得所需的资源,从而导致死锁。

这与阻塞不同,阻塞是一个进程只是等待另一个进程释放所需的资源。如果有足够的时间,阻塞将被解决。在死锁中,阻塞无法解决。

SQL 引擎可以(并且确实)检测到死锁情况。它通过选择一个或另一个进程作为死锁牺牲品并回滚来解决它。

通过识别问题并解决它来修复死锁,而不是简单地重试并希望它通过。 SQL Trace 可以帮助您识别问题。您可能需要 DBA 来帮助您。

【讨论】:

    【解决方案2】:

    一种更简单(危险性较小)的方法是更改​​有问题的六个过程,以便它们进行脏读(即 WITH(NOLOCK))。这即使在死锁中也应该可以工作,尽管您可能会得到垃圾数据。

    【讨论】:

    • 嘿,Ash,你能详细说明我在看什么样的脏读/垃圾数据...
    猜你喜欢
    • 1970-01-01
    • 2011-07-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多