IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement Web en Java Discussion :

Pool de connexion ou singleton


Sujet :

Développement Web en Java

  1. #1
    Membre éclairé Avatar de questionneuse
    Inscrit en
    Décembre 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 319
    Par défaut Pool de connexion ou singleton
    Bonsoir,

    J'ai une petite question à propos de connexion a une base de données.
    J'ai développé un pattern singleton pour me connecter à ma base, c'est pratique puisque du coup je ne ferme jamais ma connexion et plusieurs utlisateurs peuvent du coup l'utiliser, voici mon code:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    	public static DBConnection getInstance() throws Exception {		 
    		if (DBConnection.dbconnection == null) {			
    			//String path = "blabla";
    			String path = "blabla";
    			props.load(new FileInputStream(path));	
    			//mettre en place le fichier de log	la première fois
    			PropertyConfigurator.configure(props.getProperty("pathLog4j"));
    			setLog4j(Logger.getLogger("DBConnection.class"));
    			if(Logger.getLogger("DBConnection.class") == null)
    				System.out.println("La mise en place du système de log n'a pas fonctionné ");
    			else
    				log4j.log(Level.INFO,"Le système de log est mis en place: "+ getLog4j().getName());
    			log4j.log(Level.INFO, "pathLog4j: "+props.getProperty("pathLog4j"));
    			DBConnection.dbconnection = new DBConnection();
    			log4j.log(Level.INFO, "DBConnection.dbconnection = new DBConnection();");
    		}
    		return DBConnection.dbconnection;
    	}
     
    	public Connection getConnection() throws Exception {
     
    		if (DBConnection.dbconnection == null)
    			throw new Exception("Singleton non initialisé");
    		if (DBConnection.conn != null && !DBConnection.conn.isClosed())			
    		{
    			return DBConnection.conn;
    		}
    		else
    			log4j.log(Level.INFO, "Connection == null");
    		try {
    			 DBConnection.conn = getConnection3();
    		} catch (Exception ex) {
    			log4j.log(Level.FATAL, "Erreur lors du chargement du dataSource");
    			ex.printStackTrace();
    			throw new Exception("Erreur lors du chargement du dataSource");
    		}
    		return conn; 
    	}
     
    	private static Connection getConnection3() throws Exception {
    		if (DBConnection.conn != null && !DBConnection.conn.isClosed())
    		{
    			return DBConnection.conn;
    		}
     
    		user = props.getProperty("user");
    		password = props.getProperty("password");
    		host = props.getProperty("host");
    		port = props.getProperty("port");
    		dbname = props.getProperty("dbname");
     
    		try {
    			String url = "jdbc:mysql://" + host +":"+port+ "/" + dbname;
    			log4j.log(Level.INFO, "url: "+ "jdbc:mysql://" + host +":"+port+ "/" + dbname);
    			Class.forName("com.mysql.jdbc.Driver").newInstance();
    			DBConnection.conn = DriverManager.getConnection(url, user, password);
    			log4j.log(Level.INFO, "Connection DB réussie");
    		} catch (Exception e) {
    			log4j.log(Level.FATAL, "Echec de la connection DB" + e);
    		} 
    		return DBConnection.conn;
    	}
    Et j'ai lu par ci par là que ce n'était pas bien qu'il fallait passer par un pool de connexion, je ne comprend pas pourquoi c'est mieux. Ou est l'avantage? et surtout est ce ma méthode est dangereuse?

    Merci pour votre aide précieuse,

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 96
    Par défaut
    Bonjour,

    Une partie de la réponse est que si tu laisses une connexion ouverte sans activité le serveur de base de données va la fermer automatiquement au bout d'un certain temps. Du coup, a l'exécution de la prochaine requéte, ton programme va lever une SQLException.

    Le serveur de base de données est paramétré pour accepter un certain nombre de connexions simultanées. Quand le quota est atteint les connexion suivantes sont rejetées tant que les autres ne sont pas libérées. Alors, par courtoisie, il est recommandé de libérer une connexion lorsqu'elle n'est plus utilisée.

    Il est généralement recommandé d'utiliser un pool de connexion car le temps de connexion à une base de données est assez long. Le pool a en charge d'ouvrir les connexions auprès du serveur et de les maintenir ouvertes. Cela permet que lorsque tu demandes l'accès à la base tu n'as pas a attendre l'ouverture de la connexion pour envoyer ta requéte. Après, je ne sais pas comment le pool gére les connexions pour ne pas squatter les connexions comme précisé dans le point précédent.

    Voila, la réponse est incomplète mais j'espère qu'elle t'aidera tout de même.


    S. Combes

  3. #3
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Déjà ton pattern singleton ne respecte pas les bonnes pratiques.
    Constructeur privé, initialisation...

    Ensuite, c'est une très mauvaise idée de partager une connexion entre plusieurs utilisateurs.

    Soit tu crées une connexion à chaque besoin, puis tu la fermes quand tu ne t'en sers plus.
    Soit tu utilises un pool (ce qui n'empêche pas de fermer la connexion, pour la rendre au pool)

  4. #4
    Membre très actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 766
    Par défaut
    Bonjour,

    En principe un pool de connexion ne garde pas de connexion ouverte pour rien, si une première requête arrive et si aucune connexion n'est ouverte le pool se chargera de l'ouvrir. C'est à l'utilisation que cela devient intéressant, car les requêtes suivantes profiteront de la connexion déjà ouverte.
    En fonction de son paramétrage si une connexion n'est plus utilisée il la fermera de toute manière.

  5. #5
    Membre éclairé Avatar de questionneuse
    Inscrit en
    Décembre 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 319
    Par défaut
    Bonjour,

    Merci beaucoup pour vos réponses, voici mes commentaires:

    Citation Envoyé par stephane.combes Voir le message
    Bonjour,

    Une partie de la réponse est que si tu laisses une connexion ouverte sans activité le serveur de base de données va la fermer automatiquement au bout d'un certain temps. Du coup, a l'exécution de la prochaine requéte, ton programme va lever une SQLException.
    J'ai déjà réglé ce problème en augmentant la durée de non activité avant déconnexion dans le fichier de conf de ma base.

    Le serveur de base de données est paramétré pour accepter un certain nombre de connexions simultanées. Quand le quota est atteint les connexion suivantes sont rejetées tant que les autres ne sont pas libérées. Alors, par courtoisie, il est recommandé de libérer une connexion lorsqu'elle n'est plus utilisée.
    Oui mais justement je n'utilise qu'une connexion donc je ne risque donc pas d'atteindre le quota.

    Il est généralement recommandé d'utiliser un pool de connexion car le temps de connexion à une base de données est assez long. Le pool a en charge d'ouvrir les connexions auprès du serveur et de les maintenir ouvertes. Cela permet que lorsque tu demandes l'accès à la base tu n'as pas a attendre l'ouverture de la connexion pour envoyer ta requéte.
    Justement je ne me connecte qu'une fois et je laisse ouverte cette connexion. Donc je ne perd pas de temps à me reconnecter..

    Ensuite, c'est une très mauvaise idée de partager une connexion entre plusieurs utilisateurs.

    Soit tu crées une connexion à chaque besoin, puis tu la fermes quand tu ne t'en sers plus.
    Soit tu utilises un pool (ce qui n'empêche pas de fermer la connexion, pour la rendre au pool)
    J'ai dit que j'avais entendu que ce n'était pas bien et qu'il fallait apparement utiliser un pool de connexion mais ma question est POURQUOI.
    Donc ta réponse ne m'aide en rien.

    En principe un pool de connexion ne garde pas de connexion ouverte pour rien, si une première requête arrive et si aucune connexion n'est ouverte le pool se chargera de l'ouvrir. C'est à l'utilisation que cela devient intéressant, car les requêtes suivantes profiteront de la connexion déjà ouverte.
    En fonction de son paramétrage si une connexion n'est plus utilisée il la fermera de toute manière.
    ma connexion unique n'est pas ouverte pour rien, elle est la seule utilisée. Et toutes mes requetes profitent de cette connexion ouverte.

    Je ne comprend toujours pas pourquoi certains disent que ce n'est pas bien. D'autres sur certains site web recommande cette technique du singleton sur une connexion base de données.
    N'y a t-il personne qui est capable de me dire POURQUOI ca n'est pas bien, est ce que cela génére des erreurs.

    Merci d'avance

  6. #6
    Membre très actif
    Profil pro
    Inscrit en
    Février 2010
    Messages
    766
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 766
    Par défaut
    Le principal soucis est de partager ta connexion entre différents utilisateurs. Ensuite ton SGBD fermera probablement une connexion trop longtemps ouverte au boût d'un certain temps.

  7. #7
    Membre éclairé
    Profil pro
    Inscrit en
    Décembre 2009
    Messages
    96
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Décembre 2009
    Messages : 96
    Par défaut
    Citation Envoyé par questionneuse Voir le message
    POURQUOI ca n'est pas bien
    En principe ce n'est pas bien car les ressources du système ne sont pas illimitées alors il est recommandé de les libérer lorsque l'on en a plus besoin.

    Citation Envoyé par questionneuse Voir le message
    est ce que cela génére des erreurs
    Mis à part le fermeture de la connexion par le serveur déjà évoquée je n'en connais pas d'autres.

    S. Combes

  8. #8
    Membre éclairé Avatar de questionneuse
    Inscrit en
    Décembre 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 319
    Par défaut
    Citation Envoyé par Jimmy_ Voir le message
    Le principal soucis est de partager ta connexion entre différents utilisateurs.
    En quoi est ce un souci que plusieurs users utilisent la même connexion?
    J'essaie de comprendre les risques d'erreurs.

  9. #9
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Si deux utilisateurs partagent la même connexion, ils ne pourront pas exécuter leur requête en même temps. Tu auras donc des problèmes de performance à terme.

    Donc autant partir sur des bonnes pratiques, que de vouloir réinventer la roue et en faire une carrée

  10. #10
    Membre éclairé Avatar de questionneuse
    Inscrit en
    Décembre 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 319
    Par défaut
    Citation Envoyé par fr1man Voir le message
    Si deux utilisateurs partagent la même connexion, ils ne pourront pas exécuter leur requête en même temps. Tu auras donc des problèmes de performance à terme.

    Donc autant partir sur des bonnes pratiques, que de vouloir réinventer la roue et en faire une carrée
    c'est le genre de truc auquel j'ai pensé..
    Es tu sur qu'on ne peut pas effectuer 2 requetes en même temps sur une meme connection. As tu un lien?
    Merci

    ps: je ne réinvente pas la roue, certaine personnes propose cette idée..

  11. #11
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    J'étais tombé sur un lien concernant l'implémentation Mysql.

    Je ne sais pas qui propose ça, en tout cas, certainement pas des personnes reconnues.

  12. #12
    Membre éclairé Avatar de questionneuse
    Inscrit en
    Décembre 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 319
    Par défaut
    Citation Envoyé par fr1man Voir le message
    J'étais tombé sur un lien concernant l'implémentation Mysql.

    Je ne sais pas qui propose ça, en tout cas, certainement pas des personnes reconnues.
    Si tu trouves le lien ca serait sympa de me le filer.
    J'ai pas trouvé si c'est possible d'avoir plusieurs requetes simultanés sur une connexion.

  13. #13
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Je n'ai pas retrouvé le lien.

    Une connexion représente une connexion physique vers la base de données, au sens socket. Il n'est indiqué nul part que l'implémentation doive gérer du multithreading pour traiter plusieurs requêtes en même temps.

  14. #14
    Membre éclairé Avatar de questionneuse
    Inscrit en
    Décembre 2005
    Messages
    319
    Détails du profil
    Informations forums :
    Inscription : Décembre 2005
    Messages : 319
    Par défaut
    J'ai un doute sur le fait que les requetes ne s'effectuent pas en parallèle parceque lors de mes tests ou j'avais prés de 300 users je n'ai pas vu ce genre d'erreurs, attentes.
    Là, en lancant le test par exemple sur mon appli avec 2 users qui se connectent avec 2 session différentes, les 2 effectuant la même recherche, celle ci dure 3, 4 secondes (temps de la requete SQL).
    Je lance les 2 recherches à une seconde prés je devrais avoir un décalage entre les 2 de 3, 4 secondes. Or il y a même pas une seconde de décalage.

  15. #15
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    3 276
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 3 276
    Par défaut
    Admettons, mais peut-être qu'une autre implémentation du driver JDBC ne le gère pas comme cela.

    Et puis comment tu gères tes transactions, puisqu'elles sont associées à la connexion ?

Discussions similaires

  1. Pool de connexion ou singleton
    Par questionneuse dans le forum Persistance des données
    Réponses: 2
    Dernier message: 13/04/2012, 11h18
  2. [TOMCAT] pool de connexion postgres
    Par kitov dans le forum Tomcat et TomEE
    Réponses: 4
    Dernier message: 04/06/2004, 16h13
  3. [WSAD] [POOL de CONNEXION]
    Par gandia dans le forum Eclipse Java
    Réponses: 2
    Dernier message: 19/05/2004, 18h22
  4. [EJB]JBoss et Pool de connexion
    Par Kleb dans le forum Wildfly/JBoss
    Réponses: 4
    Dernier message: 20/04/2004, 12h12
  5. [tomcat 4.1] [oracle] Pool de connexion
    Par Franco dans le forum Tomcat et TomEE
    Réponses: 6
    Dernier message: 23/09/2003, 00h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo