超时已过期。在操作完成之前,超时时间已经过去或服务器未响应。该语句已终止。

412
我网站上有很多用户(每天20000-60000人次),这是一个移动文件下载站点。我可以远程访问我的服务器(Windows Server 2008-R2)。我之前收到过“服务器不可用”错误,但现在看到连接超时错误。我对此不熟悉 - 为什么会发生这种情况,如何修复它?
完整的错误信息如下:
Server Error in '/' Application. Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.
Exception Details: System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.
Source Error:
An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. [SqlException (0x80131904): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.] System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +404 System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning() +412 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363 System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +6387741 System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +6389442 System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +538 System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +689 System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +327 NovinMedia.Data.DbObject.RunProcedure(String storedProcName, IDataParameter[] parameters, Int32& rowsAffected) +209 DataLayer.OnlineUsers.Update_SessionEnd_And_Online(Object Session_End, Boolean Online) +440 NiceFileExplorer.Global.Application_Start(Object sender, EventArgs e) +163 [HttpException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.] System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context, HttpApplication app) +4052053 System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext, HttpContext context, MethodInfo[] handlers) +191 System.Web.HttpApplication.InitSpecial(HttpApplicationState state, MethodInfo[] handlers, IntPtr appContext, HttpContext context) +352 System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext, HttpContext context) +407 System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext) +375 [HttpException (0x80004005): Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated.] System.Web.HttpRuntime.FirstRequestInit(HttpContext context) +11686928 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context) +141 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) +4863749
EDIT AFTER ANSWERS: 我在Global.asax中的Application_Start如下:
protected void Application_Start(object sender, EventArgs e)
{
    Application["OnlineUsers"] = 0;

    OnlineUsers.Update_SessionEnd_And_Online(
        DateTime.Now,
        false);

    AddTask("DoStuff", 10);
}

被调用的存储过程是:

ALTER Procedure [dbo].[sp_OnlineUsers_Update_SessionEnd_And_Online]
    @Session_End datetime,
    @Online bit
As
Begin
    Update OnlineUsers
    SET
        [Session_End] = @Session_End,
        [Online] = @Online

End

我有两种获取在线用户的方法:

  1. 使用 Application["OnlineUsers"] = 0;
  2. 另一种方法是使用数据库

所以,对于第二种方法,我在 Application_Start 中重置了所有在线用户。该表中有超过482,751条记录。


2
如此写道[默认为15秒] (http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.connectiontimeout.aspx) - V4Vendetta
1
最好进行根本原因分析,造成这种问题的原因有很多。最基本的是查询结构复杂。当我从表中提取存储为十六进制值的图像时,我遇到了相同的问题。 - Vijay Kumbhoje
除了上述原因,我还要补充一个:锁定超时:https://learn.microsoft.com/en-us/sql/t-sql/statements/set-lock-timeout-transact-sql 如果此线程等待锁定时间过长,则会根据上述文档超时。 - Herbert Yu
在服务中重新启动SQL Server解决了我的问题。 - xinthose
注意:此错误的另一个可能原因是,如果您在C#/VB.NET代码中使用事务,然后从事务内调用其他访问数据库的函数/子程序。解决方法是将db传递给嵌套的函数/子程序,以便它们被视为同一事务的一部分。(注意:理想情况下,我建议不要在应用程序代码中执行事务;而是在SQL代码中执行。) - Taraz
26个回答

4

默认超时时间为15秒,如果需要更改,请将超时时间设置为0表示无限制,设置其他数字则表示超时时间为几秒。

代码中:

using (SqlCommand sqlCmd = new SqlCommand(sqlQueryString, sqlConnection))
   {
      sqlCmd.CommandTimeout = 0; // 0 = give it as much time as it needs to complete
      ...
    }

在您的Web.Config中,“Command Timeout=0;”不会超时,或者如下设置为1小时(3600秒)。
  <add name="ConnectionString" connectionString="Data Source=ServerName;User ID=UserName;Password=Password;Command Timeout=3600;" providerName="System.Data.SqlClient" />

4
这两个超时时间是不同的。你的第一个建议回答了这个问题。你的第二个建议只有在连接提供程序支持它的情况下才能起作用,而 SqlClient 不支持它。无论如何,在生产环境中,0 的超时时间都不是一个好主意。30 秒是通常的默认值。 - Suncat2000
只是澄清一下,在web.config中,“Connection Timeout = 3600”而不是“Command Timeout = 3600”(另一个不存在)。 - Ivan Paniagua

3

我在处理 sp_foo 中的大量计算时遇到了问题,需要耗费很长时间,所以我使用以下代码进行了修复:

public partial class FooEntities : DbContext
{
   public FooEntities()
         : base("name=FooEntities")
    {
        this.Configuration.LazyLoadingEnabled = false;

        // Get the ObjectContext related to this DbContext
        var objectContext = (this as IObjectContextAdapter).ObjectContext;

        // Sets the command timeout for all the commands
        objectContext.CommandTimeout = 380;
    }

2

@SilverLight.. 这显然是一个与数据库对象有关的问题。可能是查询语句编写不当或缺少索引。但目前我不建议您增加超时时间,而是应该先调查您的数据库对象的问题。

NovinMedia.Data.DbObject.RunProcedure(String storedProcName, IDataParameter[] parameters, Int32& rowsAffected) +209

在这行代码上设置断点,以查找过程名称,然后通过查看其执行计划来优化该过程。

在您发布存储过程的详细信息之前,我无法提供更多帮助。


存储过程并没有做任何花哨的东西。然而,在执行存储过程时,似乎在线用户表被锁定了。尝试使用SQL分析器查看Application_Start时发生了什么。 - Amit Rai Sharma

2
在我的情况下,我使用了 EntityFrameworkCore
由于我想要处理的输入超过了查询限制,因此出现了此错误。
对于我的情况,解决方法是将数据处理分成,通过这种方法,我能够适应限制。
是的,这需要时间,但至少可以处理所有输入记录。

1

我们在处理超时过期/达到最大池 Sqlexception时遇到了困难。为了解决问题并防止重新启动服务器或服务,我们通过SQL Server(可以通过SQL Managment Studio或T-SQL)修改MAX SERVER MEMORY变量:

DECLARE @maxMem INT = 3000 --Max. memory for SQL Server instance in MB
EXEC sp_configure 'show advanced options', 1
RECONFIGURE

这暂时修复了问题,直到再次发生。在我们的情况下,我们怀疑这与应用程序级别的连接泄漏有关。


最大服务器内存是多少?@maxMem 是什么? - Kiquenet

1

同时确保您没有未完成的交易。 :)

我进行了一些测试,并开始了一个交易以确保安全,但从未关闭它。我希望错误信息能更明确,但没关系!


1

TLDR:

  1. 如果数据量、网络设置和代码没有更改,重启应用程序和数据库服务器是最快的修复方法。我们总是遵循这个规则。
  2. 可能是需要更换的故障硬盘的指示器 - 检查系统通知。

我经常遇到各种原因导致的这个错误,并有过多种解决方案,包括:

  1. 重构我的代码,使用 SqlBulkCopy
  2. 增加超时值,如各种答案中所述或检查潜在原因(可能与数据无关
  3. 连接超时(默认15秒)- 在终止之前等待与SQL服务器建立连接的时间 - 与TCP / PORT相关 - 可以通过 故障排除清单 进行检查(非常方便的MSDN文章)
  4. 命令超时(默认30秒)- 等待查询执行的时间 - 查询执行/网络流量相关 - 还有一个故障排除过程(另一个非常方便的MSDN文章)
  5. 重新启动服务器(应用程序和DB服务器(如果分开))- 如果代码和数据没有更改,则环境必须已更改 - 必须做的第一件事。通常由补丁(操作系统,.Net Framework或SQL Server补丁或更新)引起。特别是如果出现以下超时异常(即使我们不使用Azure):
    • System.Data.Entity.Core.EntityException:发生了一个异常,很可能是由于瞬态故障引起的。如果您正在连接到SQL Azure数据库,请考虑使用SqlAzureExecutionStrategy。 ---> System.Data.Entity.Core.EntityCommandExecutionException:执行命令定义时发生错误。有关详细信息,请参见内部异常。 ---> System.Data.SqlClient.SqlException:从服务器接收结果时发生传输级错误。 (提供程序:TCP Provider,错误:0 - 信号量超时已过期。)---> System.ComponentModel.Win32Exception:信号量超时已过期

如何重构以使用SqlBulkCopy? - Kiquenet

1

我曾经遇到过这个问题,我的情况是在SQL中有一个未提交的事务。当我提交后,问题就解决了。


1

我曾经遇到过这个问题,当我将我的查询从ADO.Net转移到Dapper时,问题就解决了。


1
我们最近升级到了SqlClient (Microsoft.Data.SqlClient)的NuGet版本,但是发现其中存在一个bug。这个bug在1.x版本周期内被引入,并已经被修复。修复将在2.0.0版发布时提供,目前尚未发布,但可以使用预览版。您可以在此处查看详细信息: https://github.com/dotnet/SqlClient/issues/262

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接