2008-09-27 8 views
7

J'ai une application qui cause beaucoup de maux de tête. C'est une application .NET qui se connecte à SQL Server 2005 via un service Web. Le programme a une grille qui est remplie par une procédure stockée qui s'exécute depuis longtemps et qui est susceptible d'expirer. Dans le cas où il expire et qu'une exception SqlException est levée, il n'y a pas de gestion d'exécution pour fermer la connexion.Quelles sont les conséquences de ne pas fermer la connexion à la base de données après une erreur?

Quelles sont les conséquences réelles de cette situation? Je pense que le framework ou SQL Server s'en charge probablement d'une façon ou d'une autre mais je ne suis pas sûr.

Ajout Le programme fonctionne toujours bien le matin, mais après environ une heure d'utilisation, il ne fonctionne pratiquement plus. Le problème n'est pas que je ne sais pas comment coder la connexion correctement. J'ai besoin de savoir si ces symptômes pourraient être traités par les connexions non fermées. C'est un gros problème de changer le code de production et je voudrais savoir qu'il est au moins possible que cela soit le problème.

Conclusion J'ai généré cette défaillance sur des centaines de connexions simultanées. Je n'ai jamais pu reproduire la condition d'échec dans l'environnement d'application. Les meilleures pratiques marquées répondent comme correctes. Merci tout le monde.

+0

Je pense que l'étiquette aurait dû être sql-server et non deux étiquettes distinctes que les questions affichées –

+0

noté. Je vous remercie. –

+0

Il semble que le regroupement de connexions soit activé dans votre environnement de production. Avec la mise en commun, les connexions ne sont pas fermées même si vous leur dites de fermer, donc peu importe que vous ne les fermiez pas. – MusiGenesis

Répondre

6

Depuis un SqlConnection ferme tout en se débarrassant i l'habitude d'utiliser cette syntaxe

using (SqlConnection conn = new SqlConnection()) 
{ 
    // SqlCode here 
} 
2

Il existe une limite de connexion; Si votre application se bloque fréquemment et ne ferme pas les connexions automatiquement, les nouvelles demandes de connexion seront refusées. Cela dit, les connexions expirent après un certain temps si elles ne sont pas fermées.

0

Vous pourriez manquer de connexions disponibles si cela arrive souvent assez, vous devez utiliser un partout où vous exécutez une commande pour fermer la connexion.

0

Le garbage collector finalisera éventuellement votre objet de connexion ouvert, mais vous ne saurez pas quand le GC reviendra la prochaine fois. Jusque-là, vous pourriez manquer de connexions dans votre piscine si vous avez beaucoup de trafic ou s'il s'agit d'un serveur sql partagé. Pourquoi ne pas le jeter dans la section finale de votre bloc try/catch?

finally 
{ 
    if (cn != null) 
    { 
     cn.Dispose(); 
     cn = null; 
    } 
} 

Cela doit être fait dans la méthode de service Web évidemment.

+0

qui est fait automatiquement dans un bloc utilisant –

+0

Vrai, mais évidemment il n'utilise pas ... – Codewerks

+0

Pourquoi voter une bonne réponse? Je ne comprends pas ... – Codewerks

0
try 
{ 
    sqlCommandObject.Execute(); // this line will throw a timeout exception 
} 
finally 
{ 
    sqlConnectionObject.Close(); // this will execute no matter what happens 
} 
+0

Je pense que la recommandation de MS et d'autres était d'utiliser Dispose() ou comme Pablo l'a souligné, un bloc utilisant. Dispose() appelle Close() sur l'objet de connexion et effectue un autre nettoyage si nécessaire. – Codewerks

+0

Cette réponse est "correcte". http://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlconnection.aspx "Fermer et Dispose sont fonctionnellement équivalents." –

1

Si l'application cesse de fonctionner au bout d'une heure environ, cela pourrait être causé par des connexions non fermées/éliminées.

1

Voilà pourquoi le mot-clé « en utilisant » est si important lors de l'utilisation ADO.Net

using (SqlConnection conn = new SqlConnection()) 
{ 
    ... 
} 

Cela force un type de Garbage Collection déterministe sur l'objet ADO.Net en utilisant l'interface IDispose.

La plupart des codes de base de données utilisent un grand nombre de clauses 'using' imbriquées à cette fin.

+0

L'interface IDispose n'a rien à voir avec la récupération de place. Cela force la libération déterministe des ressources non gérées. – Joe

+0

Joe, votre affirmation est incorrecte. IDispose n'a rien à voir avec les ressources non managées. Découvrez http://www.codeproject.com/KB/mcpp/garbage_collection.aspx, par exemple. – kervin