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


295

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

完整错误如下:

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

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

源错误:

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

堆栈跟踪:

[SqlException(0x80131904):超时已过期。在操作完成之前超时或服务器没有响应。该语句已终止。]
System.Data.SqlClient.SqlConnection.OnError(SqlException异常,布尔型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,字符串resetOptionsString)+6387741
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔returnStream,布尔异步)+6389442
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean resultB,StringResultA,StringResult 538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult结果,字符串methodName,布尔型sendToPipe)+689
System.Data.SqlClient.SqlCommand.ExecuteNonQuery()+
327 NovinMedia.Data.DbObject.RunProcedure(StringstoredProcName,IDataParameter []参数,Int32和受影响的行)+209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online(对象Session_End,布尔在线)+440
NiceFileExplorer.Global.Application_Start(对象发送者,EventArgs e)+163

[HttpException(0x80004005):超时已过期。在操作完成之前超时或服务器没有响应。该语句已终止。]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext上下文,HttpApplication应用)+405205​​3
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext,HttpContext上下文,MethodInfo []处理程序)+191
System.Web.HttpApplication。 InitSpecial(HttpApplicationState状态,MethodInfo []处理程序,IntPtr appContext,HttpContext上下文)+352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr appContext,HttpContext上下文)+407
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr appContext)+375

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


回答后:
我的Application_Start输入Global.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,我在重新设置了所有OnlineUsers Application_Start。该表中有超过482,751条记录。


1
就像这里所说的,默认是15秒
V4仇杀

1
最好进行根本原因分析,有多种原因导致此类问题。最基本的是查询的复杂结构。当我获取存储为表中十六进制值的图像时,我遇到了同样的问题。
Vijay Kumbhoje 2015年

除上述原因外,我还要再添加一个:锁定超时:docs.microsoft.com/en-us/sql/t-sql/statements / ...如果此线程等待锁定的时间太长,则会基于以下原因超时以上文件。
赫伯特·于

Answers:


344

看起来您的查询所花的时间比应该花的时间更长。从堆栈跟踪和代码中,您应该能够确定确切的查询内容。

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

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

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

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

exec sp_updatestats

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

dbcc freeproccache

当服务器负载沉重时,您不应该这样做,因为它将在首次执行时对所有存储的proc和查询进行重新编译,因此会暂时导致性能严重下降。但是,由于您指出该问题有时会发生,并且堆栈跟踪指示您的应用程序正在启动,因此我认为您正在运行的查询仅偶尔运行一次。通过强制SQL Server不要重用以前的查询计划,可能会更好。有关如何执行此操作的详细信息,请参见此答案

我已经谈到了第三个问题,但是您可以通过手动执行查询(例如使用Sql Server Management Studio)来轻松确定查询是否需要调整。如果查询花费的时间太长,即使重置统计信息后,您可能仍需要对其进行调整。为了获得帮助,您应该在新问题中发布确切的查询。


39
我遇到了同样的错误,但在查询中“仅”花费了8秒钟的时间...而您的提示已exec sp_updatestats解决了我的问题。非常感谢!
nrod

2
解决这样的问题几乎绝不是调整超时或连接池大小的问题。您需要深入研究并找出根本原因。如果您需要解决该根本原因的帮助,则可以发表自己的问题。
Marnix van Valen 2014年

5
这当然不是僵局。它可能是由过多的阻塞引起的,但是死锁可以在一秒钟内解决,并且它们会产生不同的错误。这可能是过多的阻塞,但不是死锁。
Michael J Swart'3

1
我们确定这是命令超时而不是连接超时吗?对我来说“ System.Data.SqlClient.SqlConnection.OnError”指示连接问题。
Mike W

1
@PrashantPimpale 这取决于如果您在生产中遇到严重的问题,即错误的统计信息会导致错误的执行计划,那么可以,这可能是一个解决方案。除非出现特殊问题(例如硬件故障),否则更新统计信息不会破坏您的数据库。这可能会导致查询速度变慢。最后,这是您的电话。
Marnix van Valen

155

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

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

添加这样的代码行:

c.CommandTimeout = 0;

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


143
您还应该注意不建议使用 0值:0值表示没有限制,在CommandTimeout中应避免使用它,因为尝试执行命令将无限期等待。最好了解该命令花费多少时间,并在需要时增加超时值。
Otiel

7
我同意Otiel的意见,并拒绝接受您的回答:将commandTimeout设置为0时,您不会给Web服务器一个从不是responseig的数据库服务器中恢复的机会。其次,当您达到默认超时时,您应该考虑查看原因。在大多数情况下,修复查询比增加超时时间更好。
Maarten Kieft,2015年

10
我不会陷入不推荐它的陷阱。这对我和我的日常任务非常有用:无限超时不会停止进程完成,如果出现问题,则返回错误。简而言之,它只是让您允许查询在需要时完成,而不会在以后给您带来麻烦,因为您没有分配足够的时间来完成该过程。您还可以避免通过多线程锁定程序。
WonderWorker

2
是的,对于大型数据传输,不设置此选项没有意义。如果您要传输数百万行,那么Otiel和BlackHawkDesign所说的都是没有意义的。
bluerubez

在以数据为中心的20年开发中,我从不需要这样做。几乎总是存在一个合理的简单解决方案,该解决方案可以提供更好的性能,并且不会为单个进程整天磨掉数据库创造任何机会。绝大多数db性能问题都可以调整到更快地执行几个数量级的位置。也就是说,您等待3个小时才能完成的过程可能会调整为3分钟甚至3秒。
b_levitt

25

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

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


嗨,“或者您需要查看引起超时的SQL查询”->在sql server 2008中,我应该在哪里检查该超时?
SilverLight

您可能需要测试从DataLayer.OnlineUsers.Update_SessionEnd_And_Online调用的存储过程,因为堆栈跟踪似乎指向它。将实时数据库的副本进行测试,然后运行存储过程,并传入所需的参数(如果需要30秒钟以上才能完成),这就是您超时的原因。我假设您有权访问SQL Server Management Studio。
凯夫·里奇

是的,我可以访问sql server2008。我应该尝试一下。
SilverLight

如果您发现导致问题的存储过程,你可以运行通过数据库引擎优化顾问包含在存储过程中的查询,如果您需要任何索引等链接在这里,这将暗示msdn.microsoft.com/en-us/library /ms174202.aspx
Kev Ritchie

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次迭代在循环中调用的方法中。连接池已耗尽。适当的配置解决了问题。


这个!就是这个 我的问题是我在不等待线程的情况下触发了其他线程上的方法(因为用户不需要该方法的结果,即后台脚本)。没有处理(利用using块),我遇到了这个超时问题。这似乎解决了。
CularBytes

您是否收到连接池已达到最大值或超时超时的超时错误。在完成操作之前超时时间已过,或者服务器没有响应。因为,如果收到已达到的最大缓冲池,则可以检查泄漏的连接。但是,我正在服务器未响应错误。
Jeeva Subburaj

8

您必须设置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; }
}

7

我在3天左右就遇到了同样的问题。我注意到,由于我们的记录数量不多,我们的高级开发人员在数据库中保留了2张图像和指纹。当我尝试花费很长时间获取此十六进制值时,我计算出执行该过程的平均时间约为38秒。默认的commandtimeout为30秒,因此比运行我的存储过程所需的平均时间短。我如下设置我的命令超时

cmd.CommandTimeout = 50

并且它可以正常工作,但是有时如果您的查询花费超过50秒,则会提示相同的错误。


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;
    }

3

默认超时为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" />

2
那是两个不同的超时。您的第一个建议就是解决这个问题。仅当连接提供程序支持时,您的第二个才会起作用,而SqlClient不支持。无论如何,将超时设置为0在生产中绝不是一个好主意。30秒是通常的默认设置。
Suncat2000

2

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

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

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

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


存储过程不做任何花哨的东西。但是,似乎在执行该过程时OnlineUsers表已被锁定。尝试使用SQL事件探查器查看Application_Start
Amit Rai Sharma

2

尝试

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

然后重建索引


8
您能解释一下您的解决方案吗?
Hp93

0

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

显然,您可以增加CommandTimeout来解决此问题,但在此之前,您必须通过添加索引来优化查询。如果您在您的查询的SQL Server Management Studio中,包括实际的执行计划,那么SQL Server管理套件会建议你适当的索引。在大多数情况下,如果可以优化查询,就会摆脱超时问题。


0

TLDR

  1. 在不更改数据量,网络设置和代码的情况下,重新启动应用程序服务器和数据库服务器是最快的解决方案。我们通常会这样做
  2. 可能是需要更换的硬盘故障的指示-检查系统通知

由于各种原因,我经常遇到此错误,并且有各种解决方案,包括:

  1. 重构我的代码以使用SqlBulkCopy
  2. 增加超时值,如各种答案所述或检查根本原因(可能与数据无关
  3. 连接超时(默认15秒)-终止之前等待与SQL Server建立连接所花的时间-与TCP / PORT有关-可以通过故障排除清单进行检查(非常方便的MSDN文章)
  4. 命令超时(默认30秒)-等待查询执行需要多长时间-与查询执行/网络流量相关- 还具有故障排除过程(另一篇非常方便的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

另外,请确保您没有待处理的交易。:)

我正在做一些测试,为了安全起见开始了一笔交易,但从未关闭它。我希望错误会更明显,但哦!


0

我们经历了艰难的日子Timeout expired/max pool reached Sqlexception。作为一种工作环境,为防止重新启动服务器或服务,我们MAX SERVER MEMORY在SQL Server中修改了该变量(通过SQL Managment Studio或T-SQL):

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

这可以暂时解决问题,直到再次发生。在我们的案例中,我们怀疑这与应用程序级别的连接泄漏有关。


0

我们最近升级到SqlClientMicrosoft.Data.SqlClient)的NuGet版本,其中包含一个错误。此错误是在1.x周期的生命周期中引入的,现已修复。该修补程序将在2.0.0版本中提供,在撰写本文时尚不可用。预览可用。

您可以在此处检查详细信息:https : //github.com/dotnet/SqlClient/issues/262

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.