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

JDBC Java Discussion :

[Stratégie] Avis sur la gestion d'une connection JDBC via un filtre ?


Sujet :

JDBC Java

  1. #1
    Nouveau membre du Club
    Profil pro
    Développeur Java
    Inscrit en
    Septembre 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Septembre 2006
    Messages : 37
    Points : 36
    Points
    36
    Par défaut [Stratégie] Avis sur la gestion d'une connection JDBC via un filtre ?
    Bonjour,

    Dans le cadre d'une application web J2EE, j'ai crée un filtre qui ouvre et ferme une connection à la base de données. Cette connection est mise à disposition à chaque servlet via un request.setAttribute("connection", monObjetConnection);

    Je n'ai qu'à faire ce qui suit dans ma servlet, le reste étant géré par le filtre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     Connection con = (Connection) request.getAttribute("connection");
    Ceci est-il une pratique raisonnable ou pas ? Mon intégrateur a un peu grincé des dents en voyant un DB2ConnectionFilter dans mon web.xml, et m'a demandé une petite justification. Comment gérez-vous vos connections aux bases de données ? (je n'utilise pas d'EJB, j'ai juste des servlets et des JSP, avec une classe comportant des méthodes statiques pour les fonctions métier).

    Si j'ai raté un topic sur le sujet, je serais également ravi de le lire

  2. #2
    Membre éclairé Avatar de Pollux
    Profil pro
    Inscrit en
    Avril 2005
    Messages
    706
    Détails du profil
    Informations personnelles :
    Âge : 38
    Localisation : Suisse

    Informations forums :
    Inscription : Avril 2005
    Messages : 706
    Points : 680
    Points
    680
    Par défaut
    Les filtres n'ont pas pour objectif de fournir une connection à la base de données généralement.

    Plus simplement ce sont tes objets métiers qui accèdent à tes données et qui donc crée une connection. Après tu peux faire un pool de connection sur une classe singleton ou statique si tu veux avoir plusieurs connections.
    Pour chaque langage existe une faq / N'oubliez pas de lire les règles du forum

  3. #3
    Expert éminent
    Avatar de elitost
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Septembre 2003
    Messages
    1 985
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Septembre 2003
    Messages : 1 985
    Points : 6 566
    Points
    6 566
    Par défaut
    Cherche un peu du côté des DataSource qui te permettront d'obtenir un connexion pêchée dans un pool.

    Regarde également l'API DBUtils de chez Apache , c'est assez puissant.

    Un tuto sur le sujet :
    http://christophej.developpez.com/tutoriel/api/dbutils/

  4. #4
    Nouveau membre du Club
    Profil pro
    Développeur Java
    Inscrit en
    Septembre 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Septembre 2006
    Messages : 37
    Points : 36
    Points
    36
    Par défaut
    Hmm je me suis mal exprimé manifestement, toutes mes excuses

    En vérité, mon serveur d'application (websphere) me fournit déjà un pool de connections. J'utilise seulement le filtre pour en puiser une dans le pool ( Connection con = datasource.getConnection(); ) et mettre l'objet dans la ServletRequest ( request.setAttribute("connection", con); ).

    Du coup, le filtre se charge de récupérer une connection ouverte, et libère la ressource automatiquement après l'exécution de la servlet. Je trouvais ça pratique, mais mon intégrateur semble surpris (et pas tellement en bien) par ma méthode.

    Voyez plutôt :
    Code java : 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
    public class DB2ConnectionFilter implements Filter {
     
    	FilterConfig config = null;
     
    	private static String infoConnection = "";
     
    	public void init(FilterConfig config) throws ServletException {
    		System.out.println(config.getFilterName() + " initialisé");
    		this.config = config;
    	}
     
    	public void destroy() {
    		System.out.println(config.getFilterName() + " détruit");
    		this.config = null;
    	}
     
    	public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
    		Connection con = null;
     
    		try {
     
    			DataSource ds = DbCfg.getDataSource(); // DbCfg effectue un lookup au chargement de l'application, et garde une référence sur la DataSource.
    			con = ds.getConnection();
     
    			request.setAttribute("connection", con);
    ////////////////////////////////////////////////////////////////// ALLER
    			chain.doFilter(request, response);
    ////////////////////////////////////////////////////////////////// RETOUR
    			request.removeAttribute("connection");
    		} catch (SQLException sqlex) {
    			sqlex.printStackTrace();
    			throw new ServletException("La connection à la base de données n'a pas pu être établie pour la raison suivante : " + sqlex.getMessage());
    		} catch (ServletException servEx) {
    			servEx.printStackTrace();
    		} catch (Exception e) {
    			e.printStackTrace();
    			throw new ServletException("Une erreur s'est produite dans DB2ConnectionFilter : " + e.getMessage());			
    		}
    		finally {
    			try { con.close(); } catch (Exception e) { e.printStackTrace(); }
    		}
    	}
     
    }

  5. #5
    Expert éminent
    Avatar de djo.mos
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    4 666
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2004
    Messages : 4 666
    Points : 7 679
    Points
    7 679
    Par défaut
    A quoi bon ? Le traitement que t'as fait dans ton filtre peut très bien être mis directement dans la Servlet ou mieux encore dans la couche métier (DAO) et t'évites ainsi le passage par le request.

    Justement, tu l'as dit toi même, tu n'utilises pas EJB ni Hibernate ! Dans le cas contraire, oui, un filtre serait le bienvenu pour ouvrir une session de persistance (pas une connexion) et la fermer après le rendu de la réponse !

  6. #6
    Membre expérimenté
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Points : 1 464
    Points
    1 464
    Par défaut
    Bonjour

    Je n'aime pas trop l'utilisation d'un filtre pour gerer les connections.
    Dans ton code tu ouvre et ferme une connection a chaque fois, meme si tu n'en a pas besoin.

    Moi je prefere separer en couche Service/DAO.Le post http://developpez.net/forums/showpos...83&postcount=4 parle de la gestion de la session Hibernate, mais pour une connexion JDBC, le probleme est le meme.

    Je te conseille de stocker une connection dans une ThreadLocal au lieu de la stocker dans la request (dans le post que je t'ai donne j'ai explique l'interet de la ThreadLocal).

    Angelo

  7. #7
    Membre confirmé
    Avatar de grishka
    Inscrit en
    Janvier 2003
    Messages
    285
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 285
    Points : 499
    Points
    499
    Par défaut
    Si ton but est vraiement de réutiliser la connexion jdbc durant tout le traitement de ta requête, tu devrais effectivement utiliser le pattern ThreadLocal (en gros une classe singleton avec une variable de type ThreadLocal contenant la connexion). Tu pourrais ainsi la récupérer n'importe où (et pas seulement dans une servlet).
    Cela dit l'utilisation du filtre n'est pas trop déconnante : ca rejoins le principe du pattern "session per request" d'Hibernate. L'inconvénient est que tu risque de monopoliser une connexion jdbc trop longtemps, et du coup mettre en attente les autres utilisateurs...conclusion : c'est un pattern intéressant mais faut être sur 1) de pas avoir de traitement trop long ou 2) de pas avoir trop d'utilisateur
    "Les gens normaux croient que si ca marche, c'est qu'il n'y a rien à reparer. Les ingénieurs croient que si ca marche, c'est que ca ne fait pas encore assez de choses."
    --Scott Adams

  8. #8
    Nouveau membre du Club
    Profil pro
    Développeur Java
    Inscrit en
    Septembre 2006
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Septembre 2006
    Messages : 37
    Points : 36
    Points
    36
    Par défaut
    Merci pour les éclaircissements

    Je vais aller me renseigner du côté de ThreadLocal.

    En vérité, certains essais de performance que j'ai mené montraient que puiser une connection dans le pool prenait beaucoup de temps. C'est pour cette unique raison que j'ai essayé d'en puiser une seule et unique pour toute la durée de la requête. D'ailleurs, avec les filter-mapping, aucune connection inutile n'est ouverte (j'y ait fais attention )

    En fait, dans une ancienne version de mon appli laissée par l'ancien développeur, une nouvelle connection était puisée à chaque itération d'une boucle for (requête imbriquée). J'ai trouvé ca débile, et configuré ma datasource avec resultSetHoldability = HOLD_CURSORS_OVER_COMMIT (de façon à pouvoir effectivement imbriquer les requêtes sur la même connection). Résultat ? La servlet s'exécute 2x plus vite ! Biensûr, la même connection est monopolisée plus longtemps au lieu d'être recyclée, mais quand une page met 15 secondes à s'afficher, on est content de pouvoir la faire s'afficher en 7 secondes, hehe (bienque 7 secondes soit un temps relativement conséquent, je vous l'accorde :/). Concernant les utilisateurs en revanche, si on atteint 15 utilisateurs simultanés au niveau national ca sera un record

    Si d'autres personnes veulent s'exprimer sur le sujet, je prendrais les conseils avec plaisir, en attendant, je mets un beau [Résolu]

  9. #9
    Membre expérimenté
    Avatar de azerr
    Homme Profil pro
    Ingénieur Etude JEE/Eclipse RCP
    Inscrit en
    Avril 2006
    Messages
    942
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Drôme (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur Etude JEE/Eclipse RCP
    Secteur : High Tech - Multimédia et Internet

    Informations forums :
    Inscription : Avril 2006
    Messages : 942
    Points : 1 464
    Points
    1 464
    Par défaut
    Bonsoir,
    Je ne suis pas un expert en JDBC, mais d'apres mes souvenirs ce qui est long est de recuperer la premiere fois une connection non ouverte (datasource.getConnection()) du pooling de connection. Une fois que la connection est remis dans le pool (connection.close()), la recuperation de la connection (datasource.getConnection()) , normalement ca doit etre plus rapide.

    D'apres mon expérience, il faut essayer de garder le moins longtemps possible une connection ouverte. Avec le filter que tu as fait, tu laisse ouvert la connection lors de l'etape de transformation JSP=>HTML (sauf si tu appeles tes requetes dans ta JSP, ce que je ne conseille pas).

    Moi j'ai l'habitude d'utiliser le pooling de connection d'apache
    http://jakarta.apache.org/commons/dbcp/ qui marche plutot bien.

    Angelo

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. avis sur la gestion d'une authentification
    Par stardeus dans le forum Servlets/JSP
    Réponses: 7
    Dernier message: 07/06/2007, 13h52
  2. Avis sur la structure d'une base de données
    Par ange_dragon dans le forum Modélisation
    Réponses: 2
    Dernier message: 29/05/2007, 15h45
  3. Conseil ou avis sur la gestion des statistics
    Par lenitoy dans le forum Sybase
    Réponses: 3
    Dernier message: 28/03/2007, 12h07
  4. [MCD]Avis sur la représentation d'une composition
    Par habasque dans le forum Schéma
    Réponses: 10
    Dernier message: 06/01/2007, 20h11
  5. demande d'avis sur l'utilisation d'une date
    Par mrkinfo dans le forum VB 6 et antérieur
    Réponses: 1
    Dernier message: 27/07/2006, 19h50

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