12
votes

Comment testeriez-vous un pool de connexion?

J'ai mis en place une très simple ConnectionPool à Java. Il n'a aucune fonctionnalité de fantaisie, viennent d'obtenir / libérer des méthodes de connexion.

Comment puis-je tester cela fonctionne? P>

Je sais qu'il y a beaucoup de piscines de connexion prêtes à être utilisées là-bas, qui sont beaucoup plus fiables que ce que je vais faire, mais j'essaie simplement de pratiquer de comprendre comment le travail de la piscine de connexion. P>

merci! p>

Voici le code au cas où il aide: p >

public class PooledConnection {
    private Connection conn;
    private boolean used;

    public PooledConnection(Connection conn){
        this.conn = conn;
        this.used = false;
    }

    public void setUsed(){
        this.used = true;
    }

    public void setFree(){
        this.used = false;
    }

    public boolean isUsed(){
        return this.used;
    }

    public Connection getConnection(){
        return this.conn;
    }
}


2 commentaires

FYI, vous avez un bug. Lorsque vous créez et renvoyez une nouvelle connexion, vous ne le marquez pas comme utilisé.


@jtahlborn: Oups, tu as raison. J'ai corrigé celui-ci dans la modification. Merci.


4 Réponses :


2
votes

Les pools de connexion de la force industrielle ont la possibilité de vérifier les connexions en effectuant une connexion et en exécutant une simple requête SQL (E.G. SELECT 1 ") pour vous assurer que la connexion est viable avant de le donner. Le vôtre ne le fait pas.

Je ne vois pas où vous pouvez initialiser le pool de connexion avec un nombre fixe de connexions. L'ensemble du point d'un pool de connexion est d'amortir le coût de la création d'une connexion sur tous les clients.

Je m'inquiéterais de la conception de votre pool de connexion.

Quant aux tests, commencez simplement à écrire des tests d'unité. Puisque votre piscine sera partagée, assurez-vous d'écrire quelques tests multi-threads pour vous assurer que c'est vraiment le fil de sécurité.


4 commentaires

Merci pour vos suggestions. Je suis nouveau pour connecter des pools, alors excusez-moi pour ces questions qui sonneront probablement stupide: 1. Je conviens qu'un nombre maximal de connexion est très important et que je devrais en ajouter un, mais je dis que je devrais ouvrir un nombre fixe de Connexions lors de l'instanciation de mon ConnectionPool, ou devrais-je simplement les créer un par un (comme je le fais maintenant) jusqu'à ce qu'une valeur maximale soit atteinte?


2. Lorsque la valeur maximale est atteinte et qu'un thread demande une connexion, est-il préférable de renvoyer NULL ou d'attendre que une connexion soit libérée et le renvoie alors? - 3. L'un des points d'avoir un pool de connexion, ne pas passer de temps à ouvrir et à fermer des connexions à chaque fois qu'un threads veulent contacter la DB? Si oui, ne vérifiez pas la connexion avant de la libérer dans la direction opposée? Merci beaucoup!


Je vous recommanderais de créer un certain nombre de connexions en fonction de la valeur minimale, puis d'ajouter davantage au besoin. Si une autre connexion est demandée, c'est votre choix de créer un nouveau ou d'attendre jusqu'à ce qu'un autre soit libéré. L'utilisation d'une connexion n'est pas la question; en créer un. Vous ne fermez pas la connexion, vous le remettez simplement dans la piscine. Vérification de la connexion avant de la publier, toutes les piscines commerciales et open source vous permettent de le faire, alors je devinerais que cela ne va pas dans la direction opposée.


NBARAILLE, vous voudrez peut-être commencer une question distincte ", critique mon pool de connexion". Ou "Comment concevoirais-je un pool de connexion?". Ce fil est intéressant mais répond à peine à la question "Comment tester cela?".



14
votes

vous pouvez tester que

  • Obtenir une connexion lorsque la piscine est vide vous donne une connexion
  • Obtenir une connexion lorsqu'une connexion a déjà été obtenue et non libérée vous donne une autre connexion différente
  • libérer une connexion ne jette aucune exception
  • Obtenir une connexion après que l'on a été libéré vous donne la même connexion

    Notez qu'un tel test d'unité nécessiterait une réelle base de données, avec un véritable utilisateur et un mot de passe pour tester. Vous pouvez faire en sorte que votre piscine de connexion dépend d'une source de données et de créer votre ConnectionPool à l'aide d'un simturage de connexions de simulation de DataSource, afin de pouvoir tester la classe sans dépendre d'une base de données réelle.


0 commentaires

3
votes

Pour un test d'intégration, vous pouvez utiliser dbunit pour charger la base de données avec des données préparées, puis écrire des tests qui Requête la base de données.

Pour un test de l'unité, vous pouvez envisager d'utiliser une bibliothèque moqueuse telle que Mockito pour vous assurer que vous obtenez le comportement attendre. Aucune base de données nécessaire dans ce cas. [EDIT: Toutefois, en raison des appels de méthode statiques tels que DriverManager.geconnection (), cela nécessitera une certaine injection de refactoring et / ou de dépendance.]

En combinant à la fois les tests d'unités et les tests d'intégration (et mélangez dans certains tests d'unités multi-threads), vous pouvez aller très loin pour tester votre travail.


6 commentaires

Mockito ne vous aidera pas si le code reste tel qu'il est, car la seule dépendance qu'elle a est la méthode statique DriverManager.geconnection, qui n'est pas maquillée.


Bon point. Cela peut être utile avec une injection de refactorisation / dépendance. Je vais éditer.


@JB NIZET, @Michael Pâques: J'ai essayé d'utiliser autant que possible (par exemple, la connexion groupée ne crée pas sa propre connexion, mais elle est donnée un par le constructeur. Mais je ne peux penser à aucune façon pour le ConnectionPool de ne pas compter sur drivermanager.geconnection (), comment puis-je faire ça?


Pas nécessairement élégant, mais ici est un moyen: définissez une interface appelée connectable, qui a une méthode getconnection (). Écrire DefaultConnectableImpl, qui implémente cette interface en appelant la drivermanager.geconnection (). Maintenant, si votre classe reçoit une connexion connectable dans la CTOR, vous avez échappé à la dépendance.


@Michael Easter: Oui, je viens de le comprendre il y a quelques minutes, c'est une excellente idée, je peux maintenant déclarer une moindre implémentation de cette interface et tester ma ConnectionPool sans même avoir une vraie DB pour la plupart.


@nathanb fwiw, il s'agit d'un exemple concret du principe "peut être simplifié en introduisant un nouveau niveau d'indirection".



0
votes

Vous devez également tester la concurrence / l'évolutivité sous charge en utilisant plusieurs threads.


0 commentaires