ASP.NET SqlConnection超时问题

时间:2010-02-27 04:52:11

标签: c# asp.net sql sql-server-2005 enterprise-library

我遇到了一个令人沮丧的问题,我原本认为这是一个连接泄漏,但似乎并非如此。 secnario是这样的:此应用程序的数据访问使用Microsoft的企业库(v4)。所有数据访问调用都包含在使用

等语句中
using (DbCommand dbCommand = db.GetStoredProcCommand("sproc"))
{
     db.AddInParameter(dbCommand, "MaxReturn", DbType.Int32, MaxReturn);
     ...more code
}

现在这个应用程序的索引对数据库进行了8次调用以加载所有内容,我可以通过刷新索引大约15次来使应用程序瘫痪。似乎当数据库达到113个连接时,我收到此错误。这就是使这个奇怪的原因:

我在高流量网站上使用entlib运行了类似的代码,从来没有遇到过这个问题。

如果我删除了与数据库的所有连接并且每次刷新应用程序时都恢复并运行生产应用程序,那么我可以运行此SQL

SELECT DB_NAME(dbid) as 'Database Name', 
COUNT(dbid) as 'Total Connections' 
FROM sys.sysprocesses WITH (nolock)
WHERE dbid > 0
GROUP BY dbid

我可以看到每次页面刷新时主动增加的连接数。在具有相同连接字符串的本地框上运行相同的代码不会导致此问题。此外,如果生产网站关闭,我可以通过Visual Studio启动网站并运行正常,两者之间的唯一区别是生产站点打开了Windows身份验证而我的本地副本没有。关闭Windows身份验证似乎对服务器没有影响。

我完全不知道造成这种情况的原因或为什么SQL Server中没有处理连接。 EntLib对象不会为任何东西探索.Close()方法,所以我不能明确地关闭对象。

有什么想法? 谢谢!

修改

哇我刚注意到我从未真正发布错误消息。 Oy公司。实际的连接错误是:超时已过期。从池中获取连接之前经过的超时时间。这可能是因为所有池化连接都在使用中并且达到了最大池大小。

5 个答案:

答案 0 :(得分:0)

检查您正在执行的存储过程是否没有遇到行或表锁。此外,如果您可以尝试在另一台服务器中部署并检查应用程序是否会再次爬行。

还尝试增加SQL Server的最大允许连接数。

答案 1 :(得分:0)

认为“Timeout Expired”错误是一个普遍问题,并且可能有多种原因。增加TimeOut可以解决其中一些但不是全部。

您还可以参考以下链接进行故障排除并修复错误

http://techielion.blogspot.com/2007/01/error-timeout-expired-timeout-period.html

答案 2 :(得分:0)

可能是服务器上的配置问题吗?

如何在生产服务器上建立数据库连接? 这可能是一个值得研究的领域。

答案 3 :(得分:0)

虽然我不知道答案,但我可以建议,由于某些原因,在生产中运行时,应用程序不会关闭连接。 (说明显了)

您可能需要检查Web服务器和SQL Server之间的网络配置。高延迟网络可能导致连接无法及时关闭。

此外,它可能有助于查看以下msdn文章末尾列出的性能计数器: http://msdn.microsoft.com/en-us/library/8xx3tyca%28VS.71%29.aspx

最后,如果没有别的帮助,我会在生产中获得调试器和企业库源代码,并调试企业库中的代码,以找出连接未被关闭的原因。

愚蠢的问题是你正确关闭DataReader吗?如果不是这可能是问题,dev和prod之间的行为差​​异可能是由不同的垃圾收集模式引起的。

答案 4 :(得分:0)

我会禁用连接池并试图压制它(呵呵)。只需在连接字符串中添加“; Pooling = false”即可。

或者,也许您可​​以在页面中添加类似以下“清理”代码的内容(关闭页面卸载时打开的任何连接) - 正好在“using”子句中:

System.Web.UI.Page page = HttpContext.Current.Handler as System.Web.UI.Page;
if (page != null) {
           page.Unload += (EventHandler)delegate(object s, EventArgs e) {
                      try {
                                 dbCommand.Connection.Close();
                      } catch (Exception) {
                      } finally {
                                 result = null;
                      }
           };
}

此外,如果您的SQL服务器和IIS位于同一台计算机上(一个真正的性能助推器),请确保您已启用“共享内存”协议!