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 :

[JDBC / DAO] Comment utiliser intelligemment le JNDI et JDBC?


Sujet :

JDBC Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Par défaut [JDBC / DAO] Comment utiliser intelligemment le JNDI et JDBC?
    Bonjour à tous,

    Je ne sais pas si je suis dans la bonne section, mais bon, je tente quand même.

    Je développe une application web en JSF 2.2/Tomcat 7 qui se connecte à un Mysql. Cette dernière utilise une cinquantaine de DAOs fait maison qui sont en scope APPLICATION.
    Ces DAOs hérite tous d'une classe BaseDao dans laquelle est initié la connexion à la base de données d'une manière assez dégueulasse et qui, je pense, peut poser pas mal de problème de performances:

    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
     
    public abstract class BaseDao implements Serializable {
     
        private transient static Connection connection;
     
        static {
            try {
                Context initCtx = new InitialContext();
                DataSource ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/db");
                connection = ds.getConnection();
            } catch (NamingException ex) {
            } catch (SQLException ex) {
            }
        }
        protected Connection con;
        protected transient final ResourceBundle requests;
        protected transient final Logger log = Logger.getLogger(BaseDao.class);
        protected transient final ResourceBundle msg = ResourceBundle.getBundle("msg");
     
        public BaseDao() throws SQLException {
            this.requests = ResourceBundle.getBundle("requests");
            this.con = BaseDao.connection;
        }
     
        protected PreparedStatement prepareStatement(final String requestName) throws SQLException {
            checkConnection();
            return con.prepareStatement(requests.getString(requestName));
        }
     
        protected PreparedStatement prepareRawStatement(final String request) throws SQLException {
            checkConnection();
            return con.prepareStatement(request);
        }
     
        protected PreparedStatement prepareStatementReturnId(final String requestName) throws SQLException {
            checkConnection();
            return con.prepareStatement(requests.getString(requestName), Statement.RETURN_GENERATED_KEYS);
        }
     
        private void checkConnection() throws SQLException {
            if (this.con == null) {
                this.con = getConnection();
            }
        }
     
        private Connection getConnection() throws SQLException {
            DataSource ds;
            try {
                Context initCtx = new InitialContext();
                ds = (DataSource) initCtx.lookup("java:comp/env/jdbc/db");
                return ds.getConnection();
            } catch (NamingException ex) {
                return null;
            }
     
        }
    }
    En gros, il y a UNE connexion pour toute l'application.

    Comment devrais-je procéder pour optimiser tout ça? Une connexion par DAO (en augmentant la taille du pool dans le JNDI et le nombre de connexions max autorisés dans Mysql?). Dois-je plutot faire pour chaque méthode de mes DAOs un DataSource.getConnection et fermer la connexion en fin de méthode? Peut-être existe-t-il un tutorial "bonnes pratiques" à propos de ce que je veux faire?

    Merci pour votre aide

  2. #2
    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
    Une connexion JDBC ne doit pas être partagée par plusieurs threads.
    Si une action utilisateur = un thread, il te faut une connexion tout le long de cette action, que tu fermeras à la fin de l'action pour la rendre au pool.
    Tu peux mettre en place une couche service, au dessus de tes DAOs.
    Chaque méthode du service peut regrouper n appels à des méthodes de DAOs.
    La connexion est créée au début de l'appel de la méthode et fermée à la fin.
    Tu peux stocker cette connexion au sein d'un ThreadLocal par exemple.

  3. #3
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    D'accord avec fr1man

    J'ai du mal à comprendre l'architecture de ton application, mettre des DAO dans un scope application, c'est du jamais vu pour moi
    Comment gères-tu la synchronisation des requêtes entre plusieurs utilisateurs ?

    Dans le principe, pour une application web, c'est bien au niveau request/response que ce font l'acquisition et la libération de(s) connexion(s).
    Il pourrait être judicieux de faire une petite classe utilitaire pour ça...
    Avec une couche DAO, j'aurais même fourni la connexion aux méthodes des DAO, plus simple dans le cas d'un traitement type "facade"
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  4. #4
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Par défaut
    Merci pour vos réponses.

    J'avoue ne pas être super au point la dessus.

    Les Dao doivent donc être en scope request? Donc pour chaque requête, on aura une instanciation du Dao, et donc une acquisition de connexion?
    Je pensais que niveau performance ça allait être moyen.

  5. #5
    Modérateur
    Avatar de OButterlin
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    7 313
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 313
    Billets dans le blog
    1
    Par défaut
    Les DAO sont plutôt des classes utilitaires orientées "accès données" et qui sont appelées par ton contrôleur (par exemple).

    Tu peux implémenter le patter singleton pour limiter le nombre d'instances... (perso, c'est ce que j'utilise quand il n'y a pas d'EJB)
    Ensuite, passer la connexion en paramètre ou la prendre dans la DAO est une autre affaire.
    Si tu la passes, tu pourras faire plus de choses, par exemple gérer facilement des sous-transactions...
    Si tu la prends dans la DAO, tu peux utiliser le ThreadLocal pour la partager
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Mars 2006
    Messages
    87
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2006
    Messages : 87
    Par défaut
    Merci beaucoup.

    Je ne connaissais pas le ThreadLocal, je vais regarder ça de plus près.
    Ou alors réfléchir a changer toute l'architecture...

Discussions similaires

  1. Comment utiliser une datasource JNDI avec JDBC?
    Par KING_OF_GRACELAND dans le forum JDBC
    Réponses: 6
    Dernier message: 08/04/2008, 18h18
  2. comment utiliser les objets DAO
    Par marc_calagac dans le forum VBA Access
    Réponses: 3
    Dernier message: 21/06/2007, 21h01
  3. Réponses: 6
    Dernier message: 28/03/2007, 15h53
  4. Comment utiliser OUT ?
    Par Bouziane Abderraouf dans le forum CORBA
    Réponses: 3
    Dernier message: 20/07/2002, 09h35
  5. Réponses: 5
    Dernier message: 11/06/2002, 15h21

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