web-dev-qa-db-fra.com

Le délai d'attente a expiré. Le délai d'attente écoulé avant la fin de l'opération ou le serveur ne répond pas. La déclaration a été terminée

J'ai beaucoup d'utilisateurs sur mon site Web (20000-60000 par jour), qui est un site de téléchargement pour les fichiers mobiles. J'ai un accès à distance à mon serveur (serveur Windows 2008-R2).
J'ai déjà reçu des erreurs "Le serveur n'est pas disponible" , mais je vois maintenant une erreur de délai de connexion.
Je ne suis pas au courant de cela - pourquoi cela se produit-il et comment puis-je le réparer?

L'erreur complète est ci-dessous:

Erreur serveur dans l'application '/' Le délai d'attente a expiré. Le délai d'attente s'est écoulé avant la fin de l'opération ou le serveur ne répond pas. La déclaration a été terminée. Description: une exception non gérée s'est produite lors de l'exécution de la demande Web en cours. Consultez la trace de la pile pour plus d'informations sur l'erreur et son origine dans le code.

Détails des exceptions: System.Data.SqlClient.SqlException: le délai d'attente a expiré. Le délai d'attente s'est écoulé avant la fin de l'opération ou le serveur ne répond pas. La déclaration a été terminée.

Erreur de source:

Une exception non gérée a été générée lors de l'exécution de la requête Web en cours. Les informations concernant l'origine et l'emplacement de l'exception peuvent être identifiées à l'aide de la trace de pile d'exceptions ci-dessous.

Trace de la pile:

[SqlException (0x80131904): le délai a expiré. Le délai d'attente s'est écoulé avant la fin de l'opération ou le serveur ne répond pas. La déclaration a été terminée.]
System.Data.SqlClient.SqlConnection.OnError (exception SqlException, booléenne 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, Méthode String, résultat DbAsyncResult) +538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery (résultat DbAsyncResult, String methodName, Boolean sendToPipe) +689
System.Data.SqlClient.SqlCommand.ExecuteNonQuery () +327
NovinMedia.Data.DbObject.RunProcedure (String storageProcName, paramètres IDataParameter [], Int32 & rowsAffected) +209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online (Object Session_End, Boolean Online) +440
NiceFileExplorer.Global.Application_Start (Expéditeur d'objet, EventArgs e) +163

[HttpException (0x80004005): le délai d'attente a expiré. Le délai d'attente s'est écoulé avant la fin de l'opération ou le serveur ne répond pas. La déclaration a été terminée.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode (contexte HttpContext, application HttpApplication) +4052053
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS (intPtr appContext, contexte HttpContext, gestionnaires MethodInfo []) +191
System.Web.HttpApplication.InitSpecial (état HttpApplicationState, gestionnaires MethodInfo [], IntPtr appContext, contexte HttpContext) +352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance (IntPtr appContext, Contexte HttpContext) +407
System.Web.Hosting.PipelineRuntime.InitializeApplication (IntPtr appContext) +375

[HttpException (0x80004005): le délai d'attente a expiré. Le délai d'attente s'est écoulé avant la fin de l'opération ou le serveur ne répond pas. La déclaration a été terminée.]


EDIT APRES REPONSES:
mon Application_Start dans Global.asax est comme ci-dessous:

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

    OnlineUsers.Update_SessionEnd_And_Online(
        DateTime.Now,
        false);

    AddTask("DoStuff", 10);
}

La procédure stockée appelée est la suivante:

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

J'ai deux méthodes pour obtenir des utilisateurs en ligne:

  1. en utilisant Application["OnlineUsers"] = 0;
  2. l'autre utilisant la base de données

Donc, pour la méthode n ° 2, je réinitialise tous les OnlineUsers à Application_Start. Il y a plus de 482 751 enregistrements dans cette table.

270
SilverLight

Il semblerait que votre requête prenne plus de temps que prévu. À partir de votre trace de pile et de votre code, vous devriez pouvoir déterminer exactement quelle requête.

Ce type de délai peut avoir trois causes;

  1. Il y a une impasse quelque part
  2. Les statistiques de la base de données et/ou le cache du plan de requête sont incorrects
  3. La requête est trop complexe et doit être ajustée

Une impasse peut être difficile à résoudre, mais il est facile de déterminer si tel est le cas. Connectez-vous à votre base de données avec Sql Server Management Studio. Dans le volet de gauche, cliquez avec le bouton droit sur le nœud du serveur et sélectionnez Moniteur d'activité . Regardez les processus en cours. Normalement, la plupart seront inactifs ou en cours d'exécution. Lorsque le problème survient, vous pouvez identifier tout processus bloqué par son état. Si vous cliquez avec le bouton droit sur le processus et sélectionnez des détails , la dernière requête exécutée par le processus s'affichera.

Le deuxième problème entraînera l'utilisation par la base de données d'un plan de requête sous-optimal. Il peut être résolu en effaçant les statistiques:

exec sp_updatestats

Si cela ne fonctionne pas, vous pouvez également essayer

dbcc freeproccache

Cela ne devrait pas être le cas lorsque votre serveur est soumis à une charge importante, car il subirait temporairement un coup important en termes de performances car tous les processus et requêtes stockés sont recompilés lors de la première exécution. Cependant, puisque vous déclarez que le problème se produit parfois , et que le suivi de la pile indique que votre application est en cours de démarrage, je pense que vous exécutez une requête qui est uniquement courir de temps en temps. Il peut être préférable de forcer SQL Server à ne pas réutiliser un plan de requête précédent. Voir cette réponse pour plus de détails sur la procédure à suivre.

J'ai déjà abordé le troisième problème, mais vous pouvez facilement déterminer si la requête doit être optimisée en l'exécutant manuellement, par exemple à l'aide de Sql Server Management Studio. Si la requête prend trop de temps, même après la réinitialisation des statistiques, vous devrez probablement la régler. Pour vous aider, vous devez poster la requête exacte dans une nouvelle question.

313
Marnix van Valen

Dans votre code où vous exécutez la procédure stockée, vous devriez avoir quelque chose comme ceci:

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

Ajoutez une telle ligne de code:

c.CommandTimeout = 0;

Cela attendra le temps nécessaire à la fin de l'opération.

142
Elastep

Vous pouvez définir la propriété CommandTimeout de la commande SQL pour permettre la longue durée de la transaction SQL.

Vous devrez peut-être également examiner la requête SQL à l'origine du délai.

23
Kev Ritchie

Bien que toutes les réponses précédentes traitent de la question, elles ne couvraient pas tous les cas.

Microsoft a reconnu le problème et l'a corrigé en 2011 pour les systèmes d'exploitation pris en charge. Si vous obtenez le suivi de la pile, procédez comme suit:

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)

vous devrez peut-être mettre à jour vos assemblys .NET.

Ce problème est dû à une erreur dans l'algorithme de nouvelle tentative de connexion pour les bases de données en miroir.

Lorsque l'algorithme de nouvelle tentative est utilisé, le fournisseur de données attend la fin du premier appel de lecture (SniReadSync). L'appel est envoyé à l'ordinateur principal qui exécute SQL Server et le temps d'attente est calculé en multipliant la valeur du délai de connexion par 0,08. Cependant, le fournisseur de données définit de manière incorrecte une connexion sur un état condamné si une réponse est lente et si le premier appel SniReadSync n'est pas terminé avant l'expiration du délai d'attente.

Voir KB 2605597 pour plus de détails

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

12
matcheek

Peut-être que ce sera utile pour quelqu'un. J'ai fait face au même problème et dans mon cas, la raison était que la connexion SqlConnection a été ouverte et non pas éliminée dans la méthode que j'ai appelée en boucle avec environ 2500 itérations. Le pool de connexion était épuisé. Une bonne élimination a résolu le problème.

9
eternity

J'ai rencontré le même problème travaillé environ 3 jours. J'ai remarqué que notre nombre d'enregistrements n'est pas très élevé. Notre développeur principal conserve 2 images et une empreinte digitale dans une base de données. Lorsque j'essaie d'extraire cet hexagone prenant beaucoup de temps, je calcule le temps moyen nécessaire pour exécuter ma procédure, environ 38 secondes. La durée de commande par défaut est 30 secondes, donc son temps est inférieur à la moyenne nécessaire à l'exécution de ma procédure stockée. Je règle mon temps de commande comme ci-dessous

cmd.CommandTimeout = 50

et cela fonctionne bien, mais parfois, si votre requête prend plus de 50 secondes, elle provoquera la même erreur.

6
Vijay Kumbhoje

Vous devez définir l'attribut CommandTimeout. Vous pouvez définir l'attribut CommandTimeout dans la classe enfant 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; }
}
5
Siddarth Kanted

J'ai récemment rencontré cette erreur et, après une brève enquête, j'ai constaté que nous manquions d'espace sur le disque contenant la base de données (moins de 1 Go).

Dès que j'ai déplacé les fichiers de base de données (.mdf et .ldf) sur un autre disque du même serveur (avec beaucoup plus d'espace disque), la même page (en cours d'exécution de la requête) qui avait expiré chargée dans les trois secondes.

Une autre chose à examiner, tout en essayant de résoudre cette erreur, est la taille des fichiers journaux de la base de données. Vos fichiers journaux devront peut-être être réduits.

4
Hafiz Adewuyi

J'ai un problème avec le grand calcul dans sp_foo qui prend beaucoup de temps, donc j'ai corrigé
avec ce petit code

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
Nabeel Iqbal

@SilverLight .. Il s'agit clairement d'un problème avec un objet de base de données. Cela peut être une requête mal écrite ou des index manquants. Mais à partir de maintenant, je ne vous proposerai pas d'augmenter le délai d'attente sans examiner le problème avec vos objets de base de données.

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

Placez un point d'arrêt sur cette ligne de code pour trouver le nom de la procédure, puis optimisez-la en consultant son plan d'exécution.

Je ne peux pas vous aider davantage jusqu'au moment où vous publiez des détails sur la procédure stockée.

2
Amit Rai Sharma

essayer

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

puis reconstruisez votre index

1
maksoud

Le délai d'attente par défaut est de 15 secondes; pour le changer, 0 est illimité, tout autre nombre correspond au nombre de secondes.

Dans du code

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

Dans votre Web.Config, "Command Timeout = 0;" ne pas expirer, ou en dessous de 1 heure (3600 secondes)

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

TLDR:

  1. Le redémarrage des applications et des serveurs de base de données est le correctif le plus rapide pour lequel le volume de données, les paramètres réseau et le code n'ont pas changé. Nous le faisons toujours en règle générale
  2. Peut indiquer que le disque dur en panne a besoin d'être remplacé - vérifiez les notifications du système

J'ai souvent rencontré cette erreur pour diverses raisons et j'ai eu diverses solutions, notamment:

  1. refactoriser mon code à utiliser SqlBulkCopy
  2. des valeurs de délai d'expiration croissantes, comme indiqué dans diverses réponses ou la recherche de causes sous-jacentes ( peuvent ne pas être liées aux données )
  3. Délai de connexion (15s par défaut) - Délai d'attente d'une connexion à établir avec le serveur SQL avant de mettre fin - TCP/PORT associé - peut passer ne liste de contrôle de dépannage (article MSDN très utile)
  4. Délai d'attente de la commande (30 secondes par défaut) - Délai d'attente de l'exécution d'une requête - Exécution de la requête/trafic sur le réseau - comporte également un processus de dépannage (un autre article très utile de MSDN)
  5. Redémarrage du ou des serveurs - à la fois application et serveur de base de données (s’ils sont séparés) - lorsque le code et les données n’ont pas changé, l’environnement doit avoir changé - Tout d’abord, vous devez le faire. Généralement causé par des correctifs (correctifs ou mises à jour du système d'exploitation, .Net Framework ou SQL Server). En particulier si une exception de délai d'attente apparaît comme ci-dessous (même si nous n'utilisons pas Azure):
    • System.Data.Entity.Core.EntityException: une exception a probablement été déclenchée en raison d'une défaillance transitoire. Si vous vous connectez à une base de données SQL Azure, envisagez d'utiliser SqlAzureExecutionStrategy. ---> System.Data.Entity.Core.EntityCommandExecutionException: une erreur s'est produite lors de l'exécution de la définition de commande. Voir l'exception interne pour plus de détails. ---> System.Data.SqlClient.SqlException: une erreur de niveau de transport s'est produite lors de la réception des résultats du serveur. (fournisseur: TCP Fournisseur, erreur: 0 - le délai d'expiration du sémaphore a expiré.) ---> System.ComponentModel.Win32Exception: le délai d'expiration du sémaphore a expiré
0
user919426

Le délai d'attente a expiré car la requête SQL prend plus de temps que celle définie dans la propriété sqlCommand.CommandTimeout.

Évidemment, vous pouvez augmenter CommandTimeout pour résoudre ce problème, mais avant cela, vous devez optimiser votre requête en ajoutant un index. Si vous exécutez votre requête dans studio de gestion de serveur SQL y compris plan d'exécution réel alors studio de gestion de serveur SQL vous proposera un index approprié. Dans la plupart des cas, vous vous débarrasserez du problème de délai d'attente si vous pouvez optimiser votre requête.

0
Khabir

Assurez-vous également de ne pas avoir de transaction en attente. :)

Je faisais quelques tests et j'ai commencé une transaction pour être sûr mais je ne l'ai jamais fermée. J'aurais aimé que l'erreur soit plus explicite, mais bon!

0
JeromeJ