Timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde. La dichiarazione è stata chiusa


296

Ho molti utenti sul mio sito Web (20000-60000 al giorno), che è un sito di download di file mobili. Ho accesso remoto al mio server (windows server 2008-R2).
Ho ricevuto errori "Il server non è disponibile" prima, ma ora vedo un errore di timeout della connessione.
Non ho familiarità con questo - perché si verifica e come posso ripararlo?

L'errore completo è di seguito:

Errore del server nell'applicazione '/' Timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde. La dichiarazione è stata chiusa. Descrizione: si è verificata un'eccezione non gestita durante l'esecuzione della richiesta Web corrente. Esaminare la traccia dello stack per ulteriori informazioni sull'errore e sulla sua origine nel codice.

Dettagli eccezione: System.Data.SqlClient.SqlException: Timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde. La dichiarazione è stata chiusa.

Errore sorgente:

È stata generata un'eccezione non gestita durante l'esecuzione della richiesta Web corrente. Le informazioni relative all'origine e alla posizione dell'eccezione possono essere identificate utilizzando la traccia dello stack delle eccezioni riportata di seguito.

Stack Trace:

[SqlException (0x80131904): Timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde. L'istruzione è stata terminata.]
System.Data.SqlClient.SqlConnection.OnError (eccezione SqlException, Boolean breakConnection) +404
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning () +412
System.Data.SqlClient.TdsParser.haun , SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1363
System.Data.SqlClient.SqlCommand.FinishExecuteReader (SqlOe, Comando
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds (CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +6389442
System.Data.SqlCandandEeReExcuteReader 538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery (risultato DbAsyncResult, String methodName, Boolean sendToPipe) +689
System.Data.SqlClient.SqlCommand.ExecuteNonQuery () +327
NovinMedia.Data.DrocPodPrame , Int32 & rowsAffected) +209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online (Object Session_End, Boolean Online) +440
NiceFileExplorer.Global.Application_Start (mittente oggetto, EventArgs e) +163

[HttpException (0x80004005): Timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde. L'istruzione è stata terminata.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode (contesto HttpContext, app HttpApplication) +4052053
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS (IntPtr appContext, HttpContext) metodo
. InitSpecial (stato HttpApplicationState, gestori MethodInfo [], intPtr appContext, contesto HttpContext) +352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance (contesto IntCtr appContext, HttpContext) +407
System.Web.Hosting.Pipeline

[HttpException (0x80004005): Timeout scaduto. Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde. L'istruzione è stata terminata.]
System.Web.HttpRuntime.FirstRequestInit (contesto HttpContext) +11686928 System.Web.HttpRuntime.EnsureFirstRequestInit (contesto HttpContext) +141 System.Web.HttpRuntime.ProcessRequestNotificationPrivate (http: Equist


MODIFICA DOPO RISPOSTE: il
mio Application_Startin Global.asaxè come di seguito:

protected void Application_Start(object sender, EventArgs e)
{
    Application["OnlineUsers"] = 0;

    OnlineUsers.Update_SessionEnd_And_Online(
        DateTime.Now,
        false);

    AddTask("DoStuff", 10);
}

La procedura memorizzata chiamata è:

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

Ho due metodi per ottenere utenti online:

  1. utilizzando Application["OnlineUsers"] = 0;
  2. l'altro usando il database

Quindi, per il metodo n. 2 ho resettato tutti gli utenti online su Application_Start. Ci sono oltre 482.751 record in quella tabella.



1
Meglio fare analisi delle cause alla radice, ci sono vari motivi per causare questo problema. Più elementare è la complessa struttura di query. Ho riscontrato lo stesso problema quando ho recuperato le immagini memorizzate come valori esadecimali nella tabella.
Vijay Kumbhoje,

Oltre alle cause sopra, ne aggiungerò un'altra: Timeout blocco: docs.microsoft.com/en-us/sql/t-sql/statements/… Se questo thread attende il blocco troppo a lungo, si timeout in base a documento sopra.
Herbert Yu,

Risposte:


345

Sembra che tu abbia una query che impiega più tempo del dovuto. Dalla traccia dello stack e dal codice dovresti essere in grado di determinare esattamente quale query è.

Questo tipo di timeout può avere tre cause;

  1. C'è un punto morto da qualche parte
  2. Le statistiche del database e / o la cache del piano di query non sono corrette
  3. La query è troppo complessa e deve essere ottimizzata

Un deadlock può essere difficile da risolvere, ma è facile determinare se è così. Collegati al tuo database con Sql Server Management Studio. Nel riquadro sinistro fare clic con il pulsante destro del mouse sul nodo del server e selezionare Activity Monitor . Dai un'occhiata ai processi in esecuzione. Normalmente la maggior parte sarà inattiva o in esecuzione. Quando si verifica il problema, è possibile identificare qualsiasi processo bloccato dallo stato del processo. Se fai clic con il pulsante destro del mouse sul processo e selezioni i dettagli , verrà visualizzata l'ultima query eseguita dal processo.

Il secondo problema farà sì che il database utilizzi un piano di query non ottimale. Può essere risolto cancellando le statistiche:

exec sp_updatestats

Se non funziona, puoi anche provare

dbcc freeproccache

Non dovresti farlo quando il tuo server è sotto carico perché comporterebbe temporaneamente un grosso hit performace poiché tutti i processi e le query memorizzate vengono ricompilate al momento della prima esecuzione. Tuttavia, poiché si afferma che il problema si verifica a volte e la traccia dello stack indica che l'applicazione si sta avviando, penso che tu stia eseguendo una query che viene eseguita solo occasionalmente. Potrebbe essere meglio forzare SQL Server a non riutilizzare un piano di query precedente. Vedi questa risposta per i dettagli su come farlo.

Ho già toccato il terzo problema, ma puoi facilmente determinare se la query deve essere ottimizzata eseguendo la query manualmente, ad esempio utilizzando Sql Server Management Studio. Se il completamento della query richiede troppo tempo, anche dopo aver reimpostato le statistiche, probabilmente dovrai ottimizzarlo. Per assistenza, è necessario pubblicare la query esatta in una nuova domanda.


39
Stavo riscontrando lo stesso errore ma in una query che "solo" ha impiegato 8 secondi ... e il tuo suggerimento per aver exec sp_updatestatsrisolto il mio problema. Grazie molto!
inserito il

2
Risolvere un problema come questo non è quasi mai una questione di ottimizzazione dei timeout o delle dimensioni del pool di connessioni. Dovrai immergerti e capire la causa principale. Se hai bisogno di aiuto per risolvere la causa principale, puoi pubblicare la tua domanda.
Marnix van Valen,

5
Questo non è certamente un punto morto. Può essere causato da un blocco eccessivo, ma i deadlock vengono risolti in un secondo e generano errori diversi. Questo potrebbe essere un blocco eccessivo, ma non un deadlock.
Michael J Swart,

1
siamo sicuri che si tratti di un timeout dei comandi e non di un timeout della connessione? "System.Data.SqlClient.SqlConnection.OnError" indica un problema di connessione.
Mike W,

1
@PrashantPimpale Dipende se hai un problema serio nella produzione in cui statistiche errate danno luogo a piani di esecuzione errati, quindi, questa potrebbe essere una soluzione. Salvo problemi eccezionali (come guasti hardware), l'aggiornamento delle statistiche non interromperà il database. Potrebbe causare query più lente per un po '. Alla fine, però, è la tua chiamata.
Marnix van Valen,

155

Nel tuo codice in cui esegui la procedura memorizzata dovresti avere qualcosa del genere:

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

Aggiungi una tale riga di codice:

c.CommandTimeout = 0;

Questo attenderà il tempo necessario per il completamento dell'operazione.


144
È inoltre necessario tenere presente che il valore 0 non è consigliato : un valore di 0 indica nessun limite e deve essere evitato in CommandTimeout perché un tentativo di eseguire un comando attenderà indefinitamente. È meglio imparare quanto tempo impiega il comando e, se necessario, aumentare il valore di Timeout.
Otiel,

7
Sono d'accordo con Otiel e ho votato in negativo la tua risposta: quando imposti il ​​comando Timeout su 0 non dai al server web la possibilità di recuperare da un server di database che non risponde. In secondo luogo, quando si colpisce il timeout predefinito, è necessario considerare la causa. Nella maggior parte dei casi è meglio correggere la query piuttosto che aumentare il tempo di timeout.
Maarten Kieft,

10
Non cadrei nella trappola di non raccomandarlo. È stato molto utile per me e le mie attività programmate quotidiane: avere un timeout infinito non impedisce il completamento di un processo e la restituzione di un errore se qualcosa va storto. In poche parole, ti dà solo il permesso di terminare una query ogni volta che è necessario, senza darti problemi in seguito, perché non hai assegnato abbastanza tempo per il completamento del processo. Puoi anche evitare di bloccare il tuo programma multi-threading.
WonderWorker,

2
Sì per trasferimenti di dati di grandi dimensioni che non impostano ciò non ha senso. Se stai trasferendo milioni di righe, ciò che Otiel e BlackHawkDesign stanno dicendo non ha senso.
Bluerubez,

In 20 anni di sviluppo incentrato sui dati, non ho mai avuto bisogno di farlo. C'è quasi sempre una soluzione ragionevolmente semplice che offre prestazioni migliori e non crea l'opportunità per un singolo processo di macinare tutto il giorno in un database. La stragrande maggioranza dei problemi di prestazioni di db può essere sintonizzata su dove eseguono più rapidamente un ordine di grandezza. Cioè, quel processo che stai aspettando 3 ore per completare, probabilmente potrebbe essere sintonizzato su 3 minuti o anche 3 secondi.
b_levitt,

25

È possibile impostare la CommandTimeoutproprietà del comando SQL per consentire la transazione SQL a esecuzione prolungata.

Potrebbe anche essere necessario esaminare la query SQL che causa il timeout.


ciao "o devi guardare la query SQL che sta causando il timeout" -> in SQL Server 2008 dove devo controllare per quel timeout?
SilverLight,

Potrebbe essere necessario testare la Stored procedure chiamata da DataLayer.OnlineUsers.Update_SessionEnd_And_Online poiché la traccia dello stack sembra puntare verso di essa. Prendi una copia del database live in prova ed esegui la Stored Procedure passando i parametri richiesti, se ci vogliono più di 30 secondi per completare, ecco perché stai ottenendo un timeout. Suppongo che tu abbia accesso a SQL Server Management Studio.
Kev Ritchie,

Sì, ho accesso a SQL Server 2008. Dovrei provare la tua strada.
SilverLight,

Se trovi la procedura memorizzata che causa il problema, puoi eseguire la query contenuta nella procedura memorizzata tramite il Database Tuning Adviser che suggerirà se hai bisogno di indici ecc. Link qui msdn.microsoft.com/en-us/library /ms174202.aspx
Kev Ritchie il

12

Mentre tutte le risposte precedenti affrontano il problema, non hanno riguardato tutti i casi.

Microsoft ha riconosciuto il problema e risolto nel 2011 per i sistemi operativi supportati, quindi se ottieni la traccia dello stack come:

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)

potrebbe essere necessario aggiornare gli assembly .NET.

Questo problema si verifica a causa di un errore nell'algoritmo retry-connection per database con mirroring.

Quando viene utilizzato l'algoritmo retry, il fornitore di dati attende la fine della prima chiamata in lettura (SniReadSync). La chiamata viene inviata al computer back-end che esegue SQL Server e il tempo di attesa viene calcolato moltiplicando il valore di timeout della connessione per 0,08. Tuttavia, il fornitore di dati imposta erroneamente una connessione a uno stato condannato se una risposta è lenta e se la prima chiamata SniReadSync non viene completata prima della scadenza del tempo di attesa.

Vedere KB 2605597 per i dettagli

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


9

Forse sarà utile per qualcuno. Ho affrontato lo stesso problema e nel mio caso il motivo era che SqlConnection era aperto e non disposto nel metodo che ho chiamato in loop con circa 2500 iterazioni. Il pool di connessioni era esaurito. Lo smaltimento corretto ha risolto il problema.


Questo! esattamente questo. Il mio problema era che stavo attivando i metodi su un thread diverso senza aspettarli (perché l'utente non ha bisogno di un risultato di quel metodo, script in background). Senza eliminare (facendo uso di usingblocchi) ho questo problema di timeout. Questo sembrava risolverlo.
CularBytes,

hai ricevuto l'errore di timeout con il pool di connessioni max raggiunto o Timeout scaduto? Il periodo di timeout è trascorso prima del completamento dell'operazione o il server non risponde. Perché, se si riceve il pool massimo raggiunto, ha senso esaminare la connessione perduta. ma sto ricevendo un errore del server che non risponde.
Jeeva Subburaj,

8

Ho riscontrato lo stesso problema risolto circa 3 giorni. Ho notato che il nostro numero di record non è molto il nostro sviluppatore senior conserva 2 immagini e impronte digitali nel database. Quando provo a recuperare questi valori esadecimali impiegando molto tempo, calcolo il tempo medio per eseguire la mia procedura di circa 38 secondi. Il timeout di comando predefinito è di 30 secondi, quindi è necessario un tempo inferiore alla media per eseguire la procedura memorizzata. Ho impostato il mio timeout comando come di seguito

cmd.CommandTimeout = 50

e funziona correttamente, ma a volte se la query richiede più di 50 secondi, verrà visualizzato lo stesso errore.


8

Devi impostare l'attributo CommandTimeout. È possibile impostare l'attributo CommandTimeout nella classe figlio DbContext.

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

Ho riscontrato questo errore di recente e dopo alcune brevi indagini, ho scoperto che la causa era che stavamo esaurendo lo spazio sul disco che conteneva il database (meno di 1 GB).

Non appena ho spostato i file del database (.mdf e .ldf) su un altro disco sullo stesso server (con molto più spazio), la stessa pagina (in esecuzione della query) che era scaduta è stata caricata entro tre secondi.

Un'altra cosa da esaminare, mentre si tenta di risolvere questo errore, è la dimensione dei file di registro del database. Potrebbe essere necessario ridurre i file di registro.


3

Ho un problema con un grande calcolo in sp_foo che richiede molto tempo, quindi ho risolto
con questo piccolo codice di bit

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

Il timeout predefinito è 15 secondi, per cambiarlo, 0 è illimitato, qualsiasi altro numero è il numero di secondi.

Nel codice

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

In Your Web.Config, "Timeout comando = 0;" non andare in timeout o al di sotto di 1 ora (3600 secondi)

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

2
Sono due diversi timeout. Il tuo primo suggerimento affronta la domanda. Il secondo funzionerebbe solo se supportato dal provider di connessione, cosa che SqlClient non ha. Ad ogni modo, un timeout di 0 non è mai una buona idea in produzione. 30 secondi è il solito valore predefinito.
Suncat2000,

2

@SilverLight .. Questo è chiaramente un problema con un oggetto Database. Può essere una query scritta male o indici mancanti. Ma per ora non ti suggerirò di aumentare il timeout senza indagare il problema con gli oggetti del tuo database

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

Inserire un punto di interruzione su questa riga di codice per scoprire il nome della procedura e quindi ottimizzare la procedura osservando il suo piano di esecuzione.

Non posso aiutarti di più fino al momento in cui pubblichi dettagli sulla procedura memorizzata.


La Stored Procedure non fa cose fantasiose. Tuttavia, sembra che la tabella OnlineUsers sia bloccata durante l'esecuzione della procedura. Prova il profiler SQL per vedere cosa sta succedendo a Application_Start
Amit Rai Sharma il

2

provare

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

quindi ricostruisci il tuo indice


8
Puoi spiegare la tua soluzione?
Hp93,

0

Il timeout è scaduto perché la query sql richiede più tempo di quanto impostato nella proprietà sqlCommand.CommandTimeout.

Ovviamente puoi aumentare CommandTimeout per risolvere questo problema, ma prima di farlo devi ottimizzare la tua query aggiungendo indice. Se si esegue la query in studio di gestione di SQL Server incluso vero e proprio piano di esecuzione poi studio di gestione di SQL Server vi suggerisco di indice corretto. Nella maggior parte dei casi eliminerai il problema del timeout se puoi ottimizzare la tua query.


0

TLDR :

  1. Il riavvio dei server di applicazioni e DB è la soluzione più rapida in cui il volume di dati, le impostazioni di rete e il codice non sono cambiati. Lo facciamo sempre di regola
  2. Potrebbe essere un indicatore di guasto del disco rigido che necessita di sostituzione - controllare le notifiche del sistema

Ho riscontrato spesso questo errore per vari motivi e ho avuto varie soluzioni, tra cui:

  1. refactoring del mio codice per utilizzare SqlBulkCopy
  2. aumento dei valori di timeout, come indicato in varie risposte o verifica delle cause sottostanti ( potrebbe non essere correlato ai dati )
  3. Timeout connessione (impostazione predefinita 15s) - Quanto tempo occorre prima che venga stabilita una connessione con il server SQL prima di terminare - TCP / PORT - può passare attraverso un elenco di controllo per la risoluzione dei problemi (articolo MSDN molto utile)
  4. Comando Timeout (predefinito 30s) - Quanto tempo ci vuole per attendere l'esecuzione di una query - Esecuzione di query / traffico di rete relativo - ha anche un processo di risoluzione dei problemi (un altro articolo MSDN molto utile)
  5. Riavvio dei server - sia applicazione che DB Server (se separati) - dove codice e dati non sono cambiati, l'ambiente deve essere cambiato - Prima cosa che devi fare. Generalmente causato da patch (sistema operativo, patch .Net Framework o patch o aggiornamenti di SQL Server). In particolare se l'eccezione di timeout appare come di seguito (anche se non utilizziamo Azure):
    • System.Data.Entity.Core.EntityException: è stata sollevata un'eccezione che è probabilmente dovuta a un errore temporaneo. Se ci si connette a un database SQL Azure, considerare l'utilizzo di SqlAzureExecutionStrategy. ---> System.Data.Entity.Core.EntityCommandExecutionException: si è verificato un errore durante l'esecuzione della definizione del comando. Vedere l'eccezione interna per i dettagli. ---> System.Data.SqlClient.SqlException: si è verificato un errore a livello di trasporto durante la ricezione dei risultati dal server. (provider: provider TCP, errore: 0 - Il periodo di timeout del semaforo è scaduto.) ---> System.ComponentModel.Win32Exception: Il periodo di timeout del semaforo è scaduto

0

Assicurati anche di non avere una transazione in sospeso. :)

Stavo facendo dei test e ho iniziato una transazione per essere sicuro, ma non l'ho mai chiusa. Vorrei che l'errore sarebbe stato più esplicito ma vabbè!


0

Abbiamo avuto momenti difficili Timeout expired/max pool reached Sqlexception. Come soluzione alternativa e per impedire il riavvio del server o del servizio, modifichiamo la MAX SERVER MEMORYvariabile in SQL Server (tramite SQL Managment Studio o T-SQL):

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

Questo risolve temporaneamente il problema fino a quando non si ripete. Nel nostro caso sospettiamo che abbia a che fare con le perdite di connessione a livello di app.


0

Di recente abbiamo aggiornato alla versione NuGet di SqlClient( Microsoft.Data.SqlClient) che contiene un bug . Questo errore è stato introdotto durante la durata del ciclo 1.x ed è già stato corretto. La correzione sarà disponibile nella versione 2.0.0 che non è disponibile al momento della stesura di questo documento. È disponibile un'anteprima.

È possibile controllare i dettagli qui: https://github.com/dotnet/SqlClient/issues/262

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.