web-dev-qa-db-fra.com

Comment forcer une connexion SqlConnection à se fermer physiquement, tout en utilisant le pooling de connexion?

Je comprends que si j'instancie un objet SqlConnection, je récupère réellement une connexion d'un pool de connexions. Lorsque j'appelle Open (), la connexion sera ouverte. Si j'appelle la méthode Close () ou Dispose () sur cet objet SqlConnection, elle est renvoyée au pool de connexions.

Cependant, cela ne me dit pas vraiment si c'est vraiment fermé ou si j'ai toujours une connexion active à la base de données.

Comment puis-je forcer une connexion SqlConnection à se fermer au niveau du réseau, ou au moins dire quand il se ferme?

Exemple:

using(SqlConnection conn = new SqlConnection(DBConnString)) {

   conn.Open();
   SqlCommand cmd = conn.CreateCommand();
   ...
   cmd.ExecuteReader(CommandBehavior.CloseConnection);
   ...
}
  • Première utilisation: 300 ms
  • Deuxième manche: 100 ms
  • Troisième manche: 100 ms
  • Après une longue attente (30 minutes): 300 ms

Si la connexion était VRAIMENT en fermeture, les deuxième et troisième exécutions devraient également durer 300 ms. Mais je sais que la connexion n'est pas vraiment fermée pour ces exécutions (j'ai vérifié le moniteur d'activité de SQL Server). Il ne faut pas plus de 200 ms pour effectuer l'authentification/etc.

Comment puis-je forcer la connexion pour vraiment fermer?

Idées

  • Est-ce que CommandBehavior.CloseConnection fonctionne? (apparemment non?)
  • Le réglage de "Taille maximale du pool = 0" dans la chaîne de connexion fonctionne-t-il? (ce serait une solution pyrrhique)
  • Est-ce que Dispose () fonctionne?

Références

36
Jeff Meatball Yang

Peut-être que SqlConnection.ClearPool ?

51
Moe Sisko

La réponse de Moe Sisko (Call SqlConnection.ClearPool) est correcte.

Parfois, vous avez besoin d'une connexion pour fermer vraiment plutôt que de retourner à la piscine. Par exemple, j'ai un test unitaire qui crée une base de données de travail, construit le schéma, teste des éléments, puis supprime la base de données de travail si tous les tests réussissent.

Lorsque le regroupement de connexions est actif, la commande drop database échoue car des connexions sont toujours actives. Du point de vue du programmeur, toutes les connexions SQLConnections sont fermées, mais comme le pool en conserve toujours une ouverte, SQL Server n'autorisera pas la suppression.

La meilleure documentation sur la gestion du regroupement de connexions est cette page sur le regroupement de connexions SQL Server sur MSDN. On ne veut pas désactiver complètement le regroupement de connexions, car cela améliore les performances avec des ouvertures et des fermetures répétées, mais il est parfois nécessaire d'appeler une "fermeture forcée" sur une connexion SQLC pour qu'elle lâche la base de données. 

Ceci est fait avec ClearPool. Si vous appelez SqlConnection.ClearPool(connection) avant de fermer/éliminer, lorsque vous fermez/disposez, cela disparaîtra vraiment.

24
Robert Calhoun

Si vous ne souhaitez pas utiliser le pool de connexions, vous devez le spécifier dans votre propriété SqlConnection.ConnectionString. Par exemple

"Data Source=MSSQL1;Database=AdventureWorks;Integrated Security=true;Pooling=false;"

L'élimination ou la fermeture de l'objet SqlConnection ne fait que fermer la connexion et la renvoyer dans le pool de connexions.

9
ZippyV

En règle générale, vous souhaitez que le pool de connexions remplisse son rôle. Vous ne souhaitez pas que la connexion se ferme réellement.

Pourquoi voulez-vous spécifiquement que la connexion ne retourne pas au pool?

3
Eamon Nerbonne

Je vois que vous utilisez .net mais comme cela est apparu dans une requête google, permettez-moi de donner une réponse Java ...

Utilisez un DataSource qui implémente Closeable () et appelez close sur le DataSource. Hikari soutient Closeable.

0
user939857