System.Data.SqlClient.SqlException:超时已过期

Posted

技术标签:

【中文标题】System.Data.SqlClient.SqlException:超时已过期【英文标题】:System.Data.SqlClient.SqlException: Timeout expired 【发布时间】:2011-01-18 02:01:53 【问题描述】:

几天前,我注意到我的 Web 应用程序给我的 sql 异常超时已过期。

我清理了几个占用更多 CPU 的存储过程并重新启动了 SQL Server 服务,我的应用程序开始像以前一样快速且没有任何延迟地工作。三四个小时后,我再次检查它,但我无法加载页面,因为它给了我异常超时过期。我检查了服务器 CPU 一切正常。我在同一 IIS 7 下还有一些其他网站,它们运行良好,没有任何例外。我再次重新启动 SQL Server 服务,我的应用程序再次恢复正常。 而且我认为这看起来像是 SQL Server 数据库的问题,但我不知道如何解决它。

所以每次遇到异常时,我都会重新启动 sql 服务,但这当然不是最好的方法。请帮我解决这个问题。

这是我得到的一个例外。

消息:类型异常 'System.Web.HttpUnhandledException' 被抛出。来源:System.Web 内部 异常:System.Data.UpdateException: 更新时出错 条目。请参阅 InnerException 细节。 ---> System.Data.SqlClient.SqlException: 超时已过。超时时间 在完成之前经过 操作或服务器不 回应。该声明已 终止。在 System.Data.SqlClient.SqlConnection.OnError(SqlException 异常,布尔型 breakConnection) 在 System.Data.SqlClient.SqlInternalConnection.OnError(SqlException 异常,布尔型 breakConnection) 在 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) 在 System.Data.SqlClient.TdsParser.Run(运行行为 runBehavior,SqlCommand cmdHandler, SqlDataReader 数据流, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) 在 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,运行行为运行行为,字符串 重置选项字符串)在 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior、RunBehavior 运行行为、 布尔返回流,布尔异步) 在 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior、RunBehavior 运行行为、 布尔返回流,字符串方法, DbAsyncResult 结果)在 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult 结果,字符串方法名,布尔值 sendToPipe) 在 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() 在 System.Data.Mapping.Update.Internal.DynamicUpdateCommand.Execute(UpdateTranslator 翻译,EntityConnection 连接,字典2 identifierValues, List1 生成的值)在 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter 适配器) --- 内部异常堆栈跟踪结束 --- 在 System.Data.Mapping.Update.Internal.UpdateTranslator.Update(IEntityStateManager stateManager,IEntityAdapter 适配器) 在 System.Data.EntityClient.EntityAdapter.Update(IEntityStateManager 实体缓存)在 System.Data.Objects.ObjectContext.SaveChanges(布尔值 接受更改期间保存)在 System.Data.Objects.ObjectContext.SaveChanges() 在 BCSCDomain.Domain.DataLayer.OtherDataLayer.UpdateHitCounter(Int32 hlistid, Int32 hcounterid) 在 BuyCarandSellCar.UsedCarProfilePage.HitCounter() 在 BuyCarandSellCar.UsedCarProfilePage.Page_Load(Object 发件人,EventArgs e) 在 System.Web.Util.CalliHelper.EventArgFunctionCaller(IntPtr fp, 对象 o, 对象 t, EventArgs e) 在 System.Web.Util.CalliEventHandlerDelegateProxy.Callback(对象 发件人,EventArgs e) 在 System.Web.UI.Control.OnLoad(EventArgs 吃 System.Web.UI.Control.LoadRecursive() 在 System.Web.UI.Page.ProcessRequestMain(布尔值 includeStagesBeforeAsyncPoint,布尔值 includeStagesAfterAsyncPoint) 堆栈 追踪:在 System.Web.UI.Page.HandleError(异常 吃 System.Web.UI.Page.ProcessRequestMain(布尔值 includeStagesBeforeAsyncPoint,布尔值 includeStagesAfterAsyncPoint) 在 System.Web.UI.Page.ProcessRequest(布尔 includeStagesBeforeAsyncPoint,布尔值 includeStagesAfterAsyncPoint) 在 System.Web.UI.Page.ProcessRequest() 在 System.Web.UI.Page.ProcessRequestWithNoAssert(HttpContext 上下文)在 System.Web.UI.Page.ProcessRequest(HttpContext 上下文)在 ASP.usedcarlistings_profilepage_aspx.ProcessRequest(HttpContext 上下文)在 c:\Windows\Microsoft.NET\Framework\v2.0.50727\Temporary ASP.NET 文件\root\79794658\835d6695\App_Web_kmrmpdbb.16.cs:line 0 在 System.Web.HttpApplication.CallHandlerExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() 在 System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean & completedSynchronously)

【问题讨论】:

【参考方案1】:

首先,是函数“UpdateHitCounter”导致了问题,但您不知道这是原因还是结果。您的查询超出了配置的完成时间。

当您有一个性能不佳的数据库时,您可以在其上运行的一种广泛的方法是将 Sql Profiler 附加到它,然后针对结果执行索引调整向导。

如果您想采用更加衡量的分类方法,您可以限制分析器仅记录需要超过 x 秒才能完成的查询,无论您认为 x 应该是什么。我通常从 5 点开始,如果没有出现任何情况,我会从那里开始工作。 Here 是该主题的入门书。

确定长时间运行的查询后,在本地副本中执行它们并检查执行计划。 Here 是这方面的入门书,但要开始寻找“表扫描”。

最终,要么您的数据库不够理想,要么您的硬件无法满足流量要求。几乎可以肯定这是第一种,这两种方法应该可以帮助您顺利进行。

【讨论】:

非常感谢您的建议。至少现在我知道从哪里开始寻找问题。 这很有趣。我删除了 HitCounter Update 查询,并且开始从不同的查询中得到相同的错误。我在旧服务器上没有任何类似的问题。数据库也一样,内存更大,还有什么问题? 这可以追溯到我所说的因果关系...命中计数器查询本身并没有导致问题...这只是最后一个没有椅子的查询.更直接地说——另一个查询(或多个查询)在命中计数器有机会完成之前消耗了所有资源。您需要使用上面列出的分类方法来找出问题查询是什么,并且必须采用迭代方法,因为修复链中最薄弱的环节将暴露下一个环节,依此类推。 至于现在发生的原因 - 有些不同。应该是流量吧。您是否因为获得更多流量而更换了盒子? 是的,我的流量越来越大,所以我从 windows server 2003、Sql server 2005 更新到 WS2008、SQL server 2008【参考方案2】:

听起来像是泄漏行为。在不了解您的一般架构的情况下,我无法说出哪种泄漏,但我可能会建议查看您所有的表,看看是否有任何东西似乎比您预期的要多。

您也可以在 SQL Management Studio 中手动运行您的存储过程,并查看哪些存储过程花费了这么长时间——也许您正在运行一个运行时间随着正常运行时间而增加的算法。

【讨论】:

您所说的“行数超出预期”是什么意思? 我的意思是,如果你对你的表应该有多大有某种直观的感觉,你可以在那里做一个健全的检查。当您编写存储过程时,您对表之间的关系有所了解,并且应该能够预测它们的相对大小。如果您知道表 A 中的插入始终对应于表 B 中的插入,那么您可能有理由认为 A 和 B 的大小相同。如果不是,那么这可能是错误的指示。

以上是关于System.Data.SqlClient.SqlException:超时已过期的主要内容,如果未能解决你的问题,请参考以下文章