簡體   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