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:
Application["OnlineUsers"] = 0;
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.
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;
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.
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.
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.
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
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.
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.
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; }
}
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.
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;
}
@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.
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
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" />
TLDR:
J'ai souvent rencontré cette erreur pour diverses raisons et j'ai eu diverses solutions, notamment:
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.
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!