Le timeout d'attente SqlException a expiré sans être atteint

De time en time, notre server lance cette exception bien connue:

Le timeout d'attente a expiré. Le timeout d'expiration s'est écoulé avant la fin de l'opération ou le server ne répond pas.

Cela arrive sous pression lorsque le server travaille sur de grosses requêtes. J'ai fait des searchs et j'ai découvert que je pouvais modifier le paramètre de timeout de connection de string de connection et / ou les propriétés du lecteur de données SqlCommand.Timeout .

Par défaut, la command sql timeout est définie sur 30 secondes et le timeout de connection sur 15 , et nous ne les remplaçons jamais.

J'ai reproduit le context et exécuté les requests de réponse à la main dans le studio de gestion. Leur durée est d' environ 1 seconde et toujours bien au-delà de 30 .

Mais étrangement, quand je jette un oeil sur les journaux du server, cette exception est lancée immédiatement l'appel de request. Je veux dire, la requête est en cours d'exécution et une milliseconde plus tard, l'exception est levée. Excusez-moi mais laissez-moi faire mon regard geek sur ce 8-o .

Pour être complet, notre instance sql est mise en miroir avec une autre en mode synchrone . Nous utilisons Ado.Net via des adaptateurs de table.

En fait, nous avons encore expérimenté ces timeouts d'attente randoms même après que READ_COMMITED_SNAPSHOT ait été défini.

Le réglage du miroir en mode asynchronous n'a pas aidé, les requêtes effectuées dans plusieurs threads étaient toujours temporellement expirées après environ 1ms, toujours sur les périodes occupées. D'autre part, la requête spécifique qui a déclenché le timeout (une instruction INSERT) s'est exécutée très rapidement (less de 1ms CPU et environ 10 lectures en moyenne).

La stack d'appels était la suivante:

à System.Data.ProviderBase.DbConnectionPool.GetConnection (DbConnection owningObject)

à System.Data.ProviderBase.DbConnectionFactory.GetConnection (DbConnection owningConnection)

à System.Data.ProviderBase.DbConnectionClosed.OpenConnection (DbConnection externalConnection, DbConnectionFactory connectionFactory)

à System.Data.SqlClient.SqlConnection.Open ()

Le timeout d'attente ne semble donc pas lié à la requête elle-même.

Selon cet autre article: Délai d'attente de plusieurs connections SQL simultanées Dans le service Windows multithread et le post de blog MSDN lié parlant d'un bogue ADO.NET, nous avons essayé de définir le timeout d'attente de connection à 150 dans la string de connection.

Vous ne pouvez pas être certain que nous connaissions ce bug, mais plus aucun timeout d'attente n'a été levé depuis ce changement.

En fin de count, après des heures de suivi et de profilage, le problème était la corrélation de deux choses:

  1. Lecture du niveau d'isolement du server Sql par défaut activé menant à des situations de blocage
  2. Des requêtes vraiment mal réglées et des procédures stockées mélangées à des tables sans index

La première cause a été fixée avec

ALTER DATABASE <dbName> SET READ_COMMITTED_SNAPSHOT ON 

La seconde avec des requests de réécriture lucides et d'indexing de tables.

Je voudrais exécuter SQL Profiler à ce stade et voir quelles requêtes sont en cours d'exécution.