【问题标题】:ASP.NET web app deadlocking - think it's caused by SQL Server lockingASP.NET Web 应用程序死锁 - 认为它是由 SQL Server 锁定引起的
【发布时间】:2010-03-06 00:54:04
【问题描述】:

我们客户的网络应用会以随机间隔突然重启。对于每次重新启动,我们都会在 Windows 事件日志中找到这样的条目:

Event Type: Warning
Event Source: W3SVC-WP
Event Category: None
Event ID: 2262
Date: 2/21/2010
Time: 1:33:52 PM
User: N/A
Computer: LIQUID-NXCFZ9DJ
Description:
ISAPI 'c:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\aspnet_isapi.dll' reported itself as unhealthy for the following reason: 'Deadlock detected'.

这种情况在 3 周内发生了 10 次,其中有几个在几个小时内发生了 2 或 3 次,并且也持续了一周以上没有发生。

在故障转储中,我们可能有 70-80 个客户端连接,如下所示:

GET request for   <path here>
Mapped To URL    <mapped path>
HTTP Version    HTTP/1.1
SSL Request    False
Time alive    00:55:24
QueryString    <query string here>
Request mapped to    
HTTP Request State    HTR_READING_CLIENT_REQUEST
Native Request State    NREQ_STATE_PROCESS

(那是 55 分钟!!!没有理由客户端连接应该那么长)

machine.config 中的相关条目:

<system.net>
<connectionManagement>
<add address="*" maxconnection="200" />
</connectionManagement>
</system.net>

和(内部):

<deployment retail="true" />
<!--<customErrors mode="Off"/>-->

<processModel autoConfig="true"
memoryLimit="60"
maxIoThreads="200"
minIoThreads="30"
minWorkerThreads="40"
maxWorkerThreads="200"
clientConnectedCheck="00:00:05" />
<httpRuntime
minFreeThreads="20"
minLocalRequestFreeThreads="10"
enableKernelOutputCache="false"
maxRequestLength="10240" />

最近一次,我们能够看到它正在发生的情况,并且看到大约 20 个查询在 Sql Server 中都处于“暂停”状态。看起来它们可能都与一个表相关(Items 表,一个非常重要的用于许多不同操作的表)。

我们不确定最好的办法是解决问题。当崩溃发生时,Sql Server 清除了。

任何关于正在发生的事情或如何找出正在发生的事情的指导,我们将不胜感激。

【问题讨论】:

  • 好问题。但请学会格式化你的问题。输入问题时,请查看黄色的“如何格式化”框。

标签: asp.net sql-server crash deadlock


【解决方案1】:

如果是死锁,则意味着死锁有一个在 SQL 之外完成的循环。这意味着您试图在持有 SQL 资源(即事务)的同时获取进程资源(即 C#'lock')。举例说明如何发生这种情况,请考虑以下场景:

  1. T1 启动 SQL 事务并在 SQL 中更新表 A
  2. T2 在 C# 中锁定一个对象
  3. T1 尝试在 C# 中锁定同一个对象,在 T2 的锁上阻塞
  4. T2 从 SQL 表 A 中读取数据,阻止 T1 的更新
  5. T1 在您的进程中等待 T2,T2 在 SQL 中等待 T1,无法检测到死锁

在 SQL 的死锁监控内部无法检测到此类情况,因为死锁循环在 SQL 外部完成。你将如何诊断这样的问题?对于循环的 SQL 服务器端,您可以使用许多强大的工具,主要是 sys.dm_exec_requests,它可以告诉您哪些请求被什么阻止了。但不幸的是,在循环的应用程序大小上,没有开箱即用的工具,所以你只能靠自己了。有经验的眼睛可以在代码检查中发现问题(在持有 C# 锁的同时执行 SQL 调用或在 SQL 事务中间获取 C# 锁是一个很大的损失),否则您必须练习一些熟练的WinDbg-fu,或者检测代码。

您还应该考虑到这根本不是死锁。您可以让您的 20 个 SQL 请求被应用程序中的普通代码缺陷阻止,例如某些请求的事务泄漏(即请求等待阻止它们提交的事务,但该事务已在代码中泄漏并且永远不会被关闭)。同样,sys.dm_exec_requests 是您的朋友。

【讨论】:

    【解决方案2】:

    使用活动监视器检查 SQL Server 中正在运行的进程。

    更新:我看到这个特定的错误可能不是 SQL。我发现这篇关于如何生成更多关于死锁的信息的文章:http://support.microsoft.com/?ID=828222

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 2019-02-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多