繁体   English   中英

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

[英]Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. The statement has been terminated

我的网站上有很多用户(每天 20000-60000),这是一个移动文件的下载网站。 我可以远程访问我的服务器(Windows 服务器 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, String resetOptionsString) +6387741
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,布尔返回流,布尔异步)+6389442
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult 结果,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(对象发送者,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 context) +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


回答后编辑:
我在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. 另一个使用数据库

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

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

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

  1. 某处出现了僵局
  2. 数据库的统计信息和/或查询计划缓存不正确
  3. 查询太复杂,需要调优

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

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

exec sp_updatestats

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

dbcc freeproccache

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

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

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

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

添加这样一行代码:

c.CommandTimeout = 0;

这将等待操作完成所需的尽可能多的时间。

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

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

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

我遇到了同样的问题,并通过在 web.config 文件中添加“连接时间”值来解决。 找到 connectionStrings 并添加Connection Timeout=3600"

这是样本

  <connectionStrings>
    <add name="MyConn" providerName="System.Data.SqlClient" connectionString="Data Source=MySQLServer;Initial Catalog=MyDB;User ID=sa;Password=123;Connection Timeout=3600" />
  </connectionStrings>

尽管所有较早的答复都解决了该问题,但它们并未涵盖所有情况。

微软已经承认了这个问题,并在 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

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

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

cmd.CommandTimeout = 50

它工作正常,但有时如果您的查询需要超过 50 秒,它会提示相同的错误。

如果您使用带有Startup.cs约定的 ASP.NET Core,则可以访问和设置查询命令超时选项,如下所示:

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContextPool<MyDbContext>(_ =>
    {
        _.UseSqlServer(Configuration.GetConnectionString("MyConnectionString"), options => 
        {
            options.CommandTimeout(180); // 3 minutes
        });
    });
}

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

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

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

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

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

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

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

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

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

尝试

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

然后重建你的索引

TLDR

  1. 在数据量、网络设置和代码没有改变的情况下,重新启动应用程序和数据库服务器是最快的修复方法。 我们总是这样做
  2. 可能表明需要更换的硬盘驱动器出现故障 - 检查系统通知

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

  1. 重构我的代码以使用SqlBulkCopy
  2. 增加超时值,如各种答案中所述或检查根本原因(可能与数据无关
  3. 连接超时(默认 15 秒)——在终止之前等待与 SQL 服务器建立连接需要多长时间——与 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 Provider,错误:0 - 信号量超时期限已过期。)---> System.ComponentModel.Win32Exception:信号量超时期限已过期

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

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

我们最近升级到了包含错误的SqlClient ( Microsoft.Data.SqlClient ) 的 NuGet 版本 此错误是在 1.x 周期的生命周期中引入的,并且已经修复。 该修复程序将在 2.0.0 版本中提供,在撰写本文时该版本不可用。 可以预览。

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

我曾经遇到过这个问题,在我的情况下是 SQL 中的未提交事务。 在我提交之后,问题就消失了。

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

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

我们在Timeout expired/max pool reached Sqlexception时遇到了困难。 作为解决方法并防止重新启动服务器或服务,我们修改 SQL Server 中的MAX SERVER MEMORY变量(通过 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

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

此外,您还需要检查单个记录是否没有在逻辑中更新,因为该位置的更新触发器也会导致超时错误。

因此,解决方案是确保在循环/光标之后执行批量更新,而不是在循环中一次一条记录。

我遇到了这个问题,当我从ADO.Net转移到Dapper进行查询时,它就消失了。

正如其他人所说,问题可能与待处理的交易有关。 在我的情况下,我必须将DbTransaction变量作为ExecuteScalar方法中的参数发送,以便正确执行该过程。

前:

ExecuteScalar(command)

后:

ExecuteScalar(command, transaction)

就我而言,我使用了EntityFrameworkCore
由于我想要处理的输入超出了查询限制,这个错误出现在我身上。
我的情况的解决方案是数据处理分成,通过这种方法,我能够适应限制。
是的,这需要时间,但至少它会处理所有输入记录。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM