超时已过期。操作完成之前经过的超时时间或服务器没有响应。该语句已终止

问题描述 投票:262回答:13

我的网站上有很多用户(每天20000-60000),这是一个移动文件的下载站点。我可以远程访问我的服务器(Windows Server 2008-R2)。 我之前收到“服务器不可用”错误,但现在看到连接超时错误。 我不熟悉这个 - 它为什么会发生,我该如何解决?

完整错误如下:

'/'应用程序中的服务器错误。超时已过期。操作完成之前经过的超时时间或服务器没有响应。该语句已终止。描述:执行当前Web请求期间发生未处理的异常。请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息。

异常详细信息:System.Data.SqlClient.SqlException:超时已过期。操作完成之前经过的超时时间或服务器没有响应。该语句已终止。

来源错误:

在执行当前Web请求期间生成了未处理的异常。可以使用下面的异常堆栈跟踪来识别有关异常的起源和位置的信息。

堆栈跟踪:

[SqlException(0x80131904):超时已过期。操作完成之前经过的超时时间或服务器没有响应。该语句已终止。] 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 []参数,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):超时已过期。操作完成之前经过的超时时间或服务器没有响应。该语句已终止。] System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context,HttpApplication app)+405205​​3 System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext,HttpContext context,MethodInfo [] handlers)+191 System.Web.HttpApplication.InitSpecial(HttpApplicationState状态,MethodInfo []处理程序,IntPtr appContext,HttpContext上下文)+352 System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext,HttpContext context)+407 System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)+375

[HttpException(0x80004005):超时已过期。操作完成之前经过的超时时间或服务器没有响应。该语句已终止。] System.Web.HttpRuntime.FirstRequestInit(HttpContext context)+11686928 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)+141 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr,HttpContext context)+4863749


编辑后编辑: 我在Application_StartGlobal.asax如下:

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. 另一个使用数据库

因此,对于方法#2,我重置了Application_Start上的所有OnlineUser。该表中有超过482,751条记录。

c# asp.net sql-server-2008-r2 timeout sqlcommand
13个回答
311
投票

看起来你的查询花费的时间比它应该的要长。从堆栈跟踪和代码中,您应该能够确切地确定查询是什么。

这种类型的超时可能有三个原因;

  1. 某处有一个僵局
  2. 数据库的统计信息和/或查询计划缓存不正确
  3. 查询过于复杂,需要进行调整

死锁可能很难解决,但很容易确定是否是这种情况。使用Sql Server Management Studio连接到数据库。在左窗格中,右键单击服务器节点,然后选择“活动监视器”。看看正在运行的进程。通常大多数将闲置或运行。出现问题时,您可以通过进程状态识别任何阻止的进程。如果右键单击该流程并选择详细信息,它将显示该流程执行的最后一个查询。

第二个问题将导致数据库使用次优查询计划。可以通过清除统计信息来解决:

exec sp_updatestats

如果这不起作用,你也可以尝试

dbcc freeproccache

当您的服务器负载很重时,不应该这样做,因为它会暂时产生很大的性能,因为所有存储过程和查询在首次执行时都会重新编译。但是,由于您有时会说出问题,并且堆栈跟踪指示您的应用程序正在启动,我认为您正在运行仅偶尔运行的查询。通过强制SQL Server不重用以前的查询计划,您可能会更好。有关如何执行此操作的详细信息,请参阅this answer

我已经触及了第三个问题,但您可以通过手动执行查询(例如使用Sql Server Management Studio)轻松确定查询是否需要调优。如果查询需要很长时间才能完成,即使重置统计信息,您也可能需要对其进行调整。有关这方面的帮助,您应该在新问题中发布确切的查询。


2
投票

@SilverLight ..这显然是Database对象的问题。它可能是写得不好的查询,也可能是缺少索引。但截至目前,我不建议您在不调查数据库对象问题的情况下增加超时

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

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

在您发布有关存储过程的详细信息之前,我无法帮助您。


1
投票

尝试

EXEC SP_CONFIGURE 'remote query timeout', 1800
reconfigure
EXEC sp_configure

EXEC SP_CONFIGURE 'show advanced options', 1
reconfigure
EXEC sp_configure

EXEC SP_CONFIGURE 'remote query timeout', 1800
reconfigure
EXEC sp_configure

然后重建你的索引


1
投票

默认超时为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中,“命令超时= 0;”不要超时,或低于1小时(3600秒)

  <add name="ConnectionString" connectionString="Data Source=ServerName;User ID=UserName;Password=Password;Command Timeout=3600;" providerName="System.Data.SqlClient" />

0
投票

超时已过期,因为sql查询所花费的时间比在sqlCommand.CommandTimeout属性中设置的时间长。

显然,您可以增加CommandTimeout来解决此问题,但在此之前,您必须通过添加索引来优化查询。如果你在Sql server management studio中运行你的查询,包括实际的执行计划,那么Sql server management studio会建议你正确的索引。如果您可以优化查询,大多数情况下您将摆脱超时问题。


0
投票

TLDR:

  1. 重新启动应用程序和数据库服务器是最快的修复,其中数据量,网络设置和代码没有更改。我们总是这样做
  2. 可能是需要更换的硬盘驱动器故障的指示 - 检查系统通知

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

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

0
投票

还要确保您没有待处理的交易。 :)

我正在做一些测试,并开始交易是安全的,但从未关闭它。我希望错误更明确但是哦!


140
投票

在运行存储过程的代码中,您应该具有以下内容:

SqlCommand c = new SqlCommand(...)
//...

添加这样一行代码:

c.CommandTimeout = 0;

这将等待操作完成所需的时间。


23
投票

您可以设置SQL命令的CommandTimeout属性以允许长时间运行的SQL事务。

您可能还需要查看导致超时的SQL查询。


12
投票

虽然所有早期的回复都解决了这个问题,但并没有涵盖所有案例。

Microsoft已承认此问题并在2011年针对受支持的操作系统进行了修复,因此如果您获得堆栈跟踪如下:

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)

您可能需要更新.NET程序集。

出现此问题是由于镜像数据库的连接重试算法中的错误。

使用重试算法时,数据提供程序等待第一次读取(SniReadSync)调用完成。该调用将发送到运行SQL Server的后端计算机,并通过将连接超时值乘以0.08来计算等待时间。但是,如果响应很慢并且在等待时间到期之前未完成第一个SniReadSync调用,则数据提供程序会错误地将连接设置为注定状态。

有关详细信息,请参阅KB 2605597

https://support.microsoft.com/kb/2605597


9
投票

也许它会对某些人有用。我遇到了同样的问题,在我的情况下,原因是SqlConnection被打开而没有放在我用循环调用大约2500次迭代的方法中。连接池已用尽。适当的处理解决了这个问题。


6
投票

我在3天左右遇到了相同的问题。我注意到我们的记录数量并不多,我们的高级开发人员在数据库中保留了2个图像和指纹。当我尝试获取这个十六进制值时需要很长时间,我计算执行我的程序的平均时间大约是38秒。默认的commandtimeout是30秒,因此它比运行我的存储过程所需的平均时间少。我将commandtimeout设置如下

cmd.CommandTimeout = 50

并且它的工作正常,但有时如果你的查询超过50秒,它将提示相同的错误。


5
投票

您必须设置CommandTimeout属性。您可以在DbContext子类中设置CommandTimeout属性。

public partial class StudentDatabaseEntities : DbContext
{
    public StudentDatabaseEntities()
        : base("name=StudentDatabaseEntities")
    {
        this.Database.CommandTimeout = 180;
    }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        throw new UnintentionalCodeFirstException();
    }

    public virtual DbSet<StudentDbTable> StudentDbTables { get; set; }
}

4
投票

我最近遇到了这个错误,经过一些简短的调查后发现原因是我们在持有数据库的磁盘上空间不足(小于1GB)。

一旦我将数据库文件(.mdf和.ldf)移出到同一服务器上的另一个磁盘(具有更多空间),就会在三秒内加载超时的同一页面(运行查询)。

在尝试解决此错误时,另一件需要调查的是数据库日志文件的大小。您的日志文件可能需要缩小。


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;
    }
© www.soinside.com 2019 - 2024. All rights reserved.