2010-05-13 5 views
0

Je n'arrive pas à trouver une explication claire du regroupement de connexions. Je construis une application en utilisant le connecteur .NET que j'ai téléchargé depuis mysql.com. L'application n'a besoin que d'une connexion db mais fonctionnera simultanément sur environ 6 machines sur mon réseau. Normalement, je crée la connexion au démarrage et je la laisse juste. Mais je vois beaucoup de messages de personnes qui disent que c'est une mauvaise pratique. Aussi, je suis préoccupé par les délais d'attente. Mon application fonctionne 24 heures sur 24, 7 jours sur 7 et il peut y avoir des périodes prolongées sans activité de base de données.Besoin d'aide pour gérer les connexions MySql

Je penche vers ce qui suit:

using (MySqlConnection conn = new MySqlConnection(connStr)) 
{ 
    conn.Open(); 
    // use connection 
} 

Mais je ne suis pas sûr que je comprends ce qui se passe en arrière-plan. Est-ce que cela ferme réellement la connexion et permet à gc de tuer l'objet, ou y a-t-il un comportement de pooling intégré qui préserve l'objet et le relance la prochaine fois que j'essaye d'en créer un?

Je ne veux certainement pas que l'application réauthentifie sur le réseau chaque fois que je frappe la base de données.

Quelqu'un peut-il me conseiller?

+0

Si vous aviez utilisé Entity Framework, vous pourriez boire de la bière maintenant! – Luiscencio

+0

Merci beaucoup à tous ceux qui ont répondu! –

Répondre

0

Il est habituel pour les fournisseurs .net d'utiliser le regroupement de connexions dans ce scénario.

La connexion devrait être juste retourner à la piscine à la fin de votre utilisation.

Je n'ai pas regardé sous le crochet avec un profileur mysql, mais j'ai du code en place qui en dépend - je n'ai pas eu de problème avec ça.

Mise à jour: Je viens de regarder les appels effectués au cours Éliminez et il n'a certainement la mise en commun de connexion à-dire qu'il finit par appeler:

internal void CloseFully() 
{ 
    if (this.settings.Pooling && this.driver.IsOpen) 
    { 
     if ((this.driver.ServerStatus & ServerStatusFlags.InTransaction) != 0) 
     { 
      new MySqlTransaction(this, IsolationLevel.Unspecified).Rollback(); 
     } 
     MySqlPoolManager.ReleaseConnection(this.driver); 
    } 
    else 
    { 
     this.driver.Close(); 
    } 
    this.driver = null; 
} 

Mise à jour 2/répondre au commentaire: l'instance MySqlConnection est un différent, comme le using statement traite juste de disposer (libérer des ressources). Pour cette raison, vous n'avez pas besoin de vérifier si elle est fermée. Le MySqlConnection utilise en interne d'autres classes/instances, c'est-à-dire s'il attrape l'instance appropriée. C'est transparent pour votre code, donc vous l'utilisez comme s'il s'agissait d'une nouvelle connexion + différente/comme dans le code que vous avez posté.

Comme vous l'avez dit, afin de pouvoir réutiliser la connexion de niveau inférieur (appelé pilote dans le code de connecteur mysql), chaque pool est déterminée par la chaîne de connexion.

+0

Ok, vous êtes juste quelques pieds au-dessus de ma tête avec celui-ci. Est-ce que cela signifie que l'objet sera remis quand j'utiliserai de nouveau? Si oui, comment sait-il quel objet (éventuellement en comparant les chaînes de connexion?) Dois-je vérifier la propriété d'état pour m'assurer que la connexion n'est pas fermée avant l'appel? J'apprécie vraiment votre temps. –

+0

@David a ajouté une mise à jour avec la réponse. – eglasius

+0

Merci d'être si généreux avec votre temps. C'était très utile. –

0

Selon this post les connexions sont maintenues en vie et mis en commun par défaut pendant 60 secondes avant d'être fermé.

0

Le modèle déconnecté est le plus utilisé dans le monde entier, mais pas abuser de l'authentification encore et encore.

Disconnected mode

Voici quelques-unes des raisons pour lesquelles vous voulez travailler déconnecté la plupart du temps:

  1. Le nombre de CLA (Licences client Accords) achetés pour votre serveur de base de données (bien, pas vraiment applicable ici comme c'est MySQL);
  2. Si trop de personnes sont connectées en même temps, cela ralentit le DBE (Database Engine);
  3. Garder les connexions ouvertes maintient le réseau occupé, et un réseau trop occupé est plus susceptible d'échouer;
  4. Lorsqu'un utilisateur modifie, disons les détails d'un client, il n'a pas besoin de conserver sa connexion au serveur de base de données et peut-être verrouiller une ligne ou une table de données, ce qui entraînerait de gros problèmes de verrouillage simultanés.

Ce code:

using(MySqlConnection conn = new MySqlConnection(connStr)) { 
    if (conn.State == ConnectionState.Closed) 
     try { 
      conn.Open(); 
     } catch (MySqlException ex) { 
      // Exception handling here... 
     } 
    // Use of connection here... 
} 

Le mot-clé using est utilisé pour éliminer automatiquement les objets instanciés à l'intérieur comme les états de référence de l'article:

définit un champ, en dehors duquel un objet ou les objets seront éliminés.

De cette façon, vous vous assurez qu'une fois la connexion n'est plus nécessaire, vous vous en débarrassez. Alors oui, une nouvelle authentification sera nécessaire une fois que cette connexion sera à nouveau instanciée, car elle n'existe plus. Il y a un petit sondage effectué ici pour une courte période, mais ce n'est pas une question dont vous devez vous inquiéter.

Connected mode

Afin d'assurer l'utilisation d'une seule telle connexion dans toute votre application, vous devez l'utiliser comme singleton. Cependant, une fois que votre chaîne de connexion change, un jour, vous devrez vous assurer que toute l'application est fermée et rouverte, afin que cette connexion obtienne une chaîne de connexion rafraîchie. Ce n'est pas viable, mais je ne connais pas votre contexte.

Utilisation de la bibliothèque Enterprise Data Access Application Bloc

Afin d'apporter votre pool de connexion facile à gérer, vous pouvez utiliser le Enterprise LibraryData Access Application Block. Le DAAB est une couche d'accès aux données entièrement configurable et facile à utiliser, conçue par des ingénieurs de Microsoft et d'autres sociétés participantes. Ensuite, la gestion du pool de connexion peut être aussi simple que 1-2-3!

Je pense que vous pourriez gagner beaucoup en utilisant le DAAB qui est entièrement configurable dans le fichier XML et nécessite très peu de maintenance.

EDIT Si je peux pousser un peu plus loin, je pourrais peut-être envisager d'utiliser le motif de conception de façades avec Factories.

Utiliser Design Pattern Façade et les usines efficacement

Avoir une façade « intelligente », il est ce que vous fournir la connexion dont vous avez besoin. À ce titre, voici un exemple simple (en supposant que vous avez un cadre de projet appelé « DefaultConnectionString »):

public static class ApplicationFacade { 
    private static readonly ApplicationFactory _applicationFactory = new ApplicationFactory(); 

    public static DefaultConnectionString { 
     get { 
      return Properties.Settings.Default.DefaultConnectionString; 
     } 
    } 

    public static IList<ICustomer> GetCustomers() { 
     using(var connection = OpenConnection()) 
      _applicationFactory.GetCustomers(connection); 
    } 

    public MySqlConnection OpenConnection() { 
     var newConnection = new MySqlConnection(DefaultConnectionString); 
     try { 
      newConnection.Open(); 
     } catch (Exception ex) { 
      // Exception handling... 
     } 
     return newConnection; 
    } 
} 

internal sealed class ApplicationFactory { 
    internal ApplicationFactory() { 
    } 

    internal IList<ICustomer> GetCustomers(MySqlConnection connection) { 
     if (connection.State != ConnectionState.Open) 
      throw new InvalidOperationException() 

     IList<ICustomer> customers = new List<ICustomer>(); 

     var command = new MySqlCommand(connection, @"select * from Customers"); 
     // Place code to get customers here... 

     return customers; 
    } 
} 

// So you'll be able to use share the same connection throught your factory whenever needed, preventing the overkill of authentication over and over again. Here's how this would be used: 

public partial class MainForm : Form { 
    private void PopulateGrid() { 
     dataGridView1.DataSource = ApplicationFacade.GetCustomers(); 
     // And you never care about the connection! All you want is the list of customers, that's all! 
    } 
} 

C'est un modèle que j'utilise souvent dans mes projets de développement. Il permet un seul point d'entrée à mes bibliothèques de classe, et ils sont très faciles à utiliser.

Eh bien, c'est peut-être plus que ce que vous avez demandé, mais j'espère que ça aide.

Questions connexes