Se souvenir de l'état de la connexion SQL dans .net?

.net c# connection-pooling dapper sqlconnection

Question

À côté de l'ancien fait connu que connection.Close() vs connection.Dispose() sont les mêmes - sauf que l'exécution de Close() sur une connexion disposée déclenche une exception lors de l'exécution de Close() sur une connexion fermée - est OK - j'ai toujours une question :

En supposant que le regroupement de connexions est activé (par défaut), pourquoi est-il important de se souvenir de l'état de la connexion?

J'ai lu cette question ici qui montre que: éviter d'ouvrir et de fermer une connexion enregistre les performances .

Cela semble logique, mais le problème est que la connexion n'est jamais fermée! il est seulement marqué pour la fermeture.

Même si je l'utilise sous une portée d' using - la disposition ferme simplement la connexion et la remet dans le pool.

Même si je voulais, je ne pouvais pas le laisser ouvert (parce que je voudrais que les autres l’utilisent) . alors j'ai dû fermer / éliminer.

En regardant Dapper qui implémente également ce comportement:

public static async Task<IEnumerable<T>> QueryAsync<T>(this...)
        {
         //...
            bool wasClosed = cnn.State == ConnectionState.Closed;
            using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader))
            {
                try
                {
                    if (wasClosed) await ((DbConnection)cnn).OpenAsync()...
                  //...
                }
                finally
                {
                    if (wasClosed) cnn.Close();
                }
            }
        }

Comme vous pouvez le voir, la "mémorisation" est implémentée ici.

nb, j'ai déjà demandé à Marc un sujet connexe qui est - pourquoi dans les échantillons dapper, il utilise à la fois GetClosedConneciton et GetOpenConnection et j'ai une réponse qui doit montrer - que Dapper peut gérer les deux scénarios. Cependant, cette question actuelle concerne la raison pour laquelle il est réinitialisé l'état des connexions.

Question:

En regardant le code Dapper, il semble qu'il se souvient de l'état et réinitialise l'état après l'opération. (Je connais aussi ce comportement de l'ancienne classe sqldataadapter)

La question est: pourquoi? Si j'ai une connexion fermée, alors je dois l'ouvrir. génial. mais pourquoi dois-je le fermer par condition? pourquoi ne pas toujours le fermer? cela ne va pas nuire à la performance car la connexion n'est pas réellement fermée - elle est seulement renvoyée au pool.

À l'inverse - Si je disposais d'une connexion ouverte, je travaillerais et je le garderais ouvert (hein ??)

Comme vous le voyez probablement, il me manque quelque chose ici. Quelqu'un peut-il s'il vous plaît jeter la lumière?

Réponse acceptée

pourquoi ne pas toujours le fermer?

L'utilisateur pourrait faire beaucoup de travail sur cette connexion. Il pourrait être associé à une transaction (la fermeture le rendrait orphelin). Il pourrait avoir des tables temporaires (la fermeture les détruirait) ou un autre état préservé de la connexion (options SET , emprunt d'identité, etc.).

Fermer une connexion ici (si elle était ouverte à l'origine) serait une chose inhabituelle et inattendue avec de multiples effets secondaires désagréables.


Réponse populaire

Si vous écrivez une fonction de bibliothèque où il est logique que les consommateurs vous transmettent un objet de connexion (quelle que soit leur saveur), la chose la plus sûre à faire est de respecter cette connexion:

  • Si vous passez un objet de connexion ouvert, ne faites aucune hypothèse à ce sujet et ne le fermez certainement pas après avoir terminé votre travail - vous ne savez pas ce que vos consommateurs ont fait ou vont faire avec.
  • Si vous passez un objet de connexion fermé, vous feriez mieux de l'ouvrir avant d'essayer de l'utiliser, et vous devriez le fermer une fois que vous avez terminé - vous savez que votre client ne peut pas par exemple ouvrir une transaction contre une connexion fermée.

Si votre code crée un objet de connexion, alors je recommande toujours que la création soit placée dans une instruction using et qu'elle soit toujours fermée lorsque vous avez terminé.

Donc, la seule chose qui me reste à dire est de bien réfléchir à la rédaction de vos fonctions et de déterminer s’il est logique que vos consommateurs vous transmettent des objets de connexion - si votre travail devait toujours être effectué de manière isolée, sens de demander par exemple une chaîne de connexion et que votre code contrôle entièrement la connexion.




Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Est-ce KB légal? Oui, apprenez pourquoi