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 - Fermeture des composants


Sujet :

JDBC Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2009
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 46
    Par défaut JDBC - Fermeture des composants
    Bonjour à tous,

    Je poste ici après avoir eu un débat avec les collègues concernant la fermeture de composants JDBC.

    La méthode est la suivante :

    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
    // Déclaration des componsants JDBC
    Connection conn = null;
    PreparedStatement stmt = null;
    ResultSet rs = null;
     
    try{
       // Ouverure et utilisation des componsants JDBC
       ...
    }
    // A noter : pas de bloc catch, les exceptions seront remontées au niveau suppérieur
    finally{
       try{rs.close();}catch(Exception e){}
       try{stmt.close();}catch(Exception e){}
       try{conn.close();}catch(Exception e){}
    }
    Les critiques remontées sont les suivantes :
    1- On catch une exception générique et non un sous type SQLException
    2- On ne log pas l'exception

    Mon avis : si une exception à lieu durant la fermeture des composants, c'est qu'en principe une exception a déja été levée dans le try{} et donc elle sera catchée au niveau supérieur. La logger ne sert donc à rien. Et de toute façon si le close() plante et que la connexion a été fermée (ex:coupure réseau) avant l'entrée dans le bloc finally, de toute façon le commit a déja eu lieu et cela ne pose aucun problème.

    Qu'en pensez-vous ? Comment avez-vous l'habitude de procéder pour fermer vos composants JDBC ? Est-ce que vous trouvez cette méthode "propre" ou pas ?

  2. #2
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 394
    Par défaut
    Bonjour,

    J'utilise le même principe que toi mais je me sers de la librairie commons apache IO qui propose une méthode pour fermer une ressource silencieusement :

    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
    /**
         * Unconditionally close a <code>Closeable</code>.
         * <p>
         * Equivalent to {@link Closeable#close()}, except any exceptions will be ignored.
         * This is typically used in finally blocks.
         * <p>
         * Example code:
         * <pre>
         *   Closeable closeable = null;
         *   try {
         *       closeable = new FileReader("foo.txt");
         *       // process closeable
         *       closeable.close();
         *   } catch (Exception e) {
         *       // error handling
         *   } finally {
         *       IOUtils.closeQuietly(closeable);
         *   }
         * </pre>
         *
         * @param closeable the object to close, may be null or already closed
         * @since Commons IO 2.0
         */
        public static void closeQuietly(Closeable closeable) {
            try {
                if (closeable != null) {
                    closeable.close();
                }
            } catch (IOException ioe) {
                // ignore
            }
        }
    Elle n'effectue le close() que si le closeable n'est pas null (chose que tu ne fais pas et qui pourrait provoquer une NullPointerException qui sera catchée par ton "catch(Exception e)").

    Sinon je trouve que ton raisonnement est le bon, ça n'a pas grand intérêt de logger une exception sur la fermeture d'une ressource, c'est bien pour cela qu'apache a fait une méthode utilitaire...

    Romain.

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

    Informations forums :
    Inscription : Août 2006
    Messages : 3 277
    Par défaut
    Ce que je fais :
    Ajouter une clause throws SQLException sur ma méthode.
    Ensuite dans le finally, je ne catche pas les exceptions du close, je les laisse remonter à l'appelant.

    Pour les remarques, je suis d'accord d'éviter de catcher les exceptions generiques (dans ce cas précis), et puis d'éviter les catchs vides.
    Puisque je laisse remonter l'exception, je ne vois pas d'interet de rajouter un log.

    Comme cela a été ajouté, je teste aussi la nullité de mes objet avant d'appeler le close.

  4. #4
    Membre averti
    Inscrit en
    Janvier 2009
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 46
    Par défaut
    Merci pour vos réponses.

    Pour rg77140, je ne connaissais pas la fonction utilitaire d'Apache, merci pour l'info. En général je procéde d'une façon similaire en créant une méthode statique JDBCCloser.close(ResultSet rs, Statement st, Connection conn) qui se charge de la fermeture des composants s'ils sont non null.


    fr1man, la je ne suis pas d'accord concernant cette méthode. Car si une exception est levée dans le finally sur le close, alors cette exception va écraser une éventuelle exception levée dans le try, et donc l'exception initiale, celle qui nous interesse, est perdue.
    De même si tu ne fais pas un try/catch pour chaque objet à fermer, il est possible que le close() sur le premier objet plante, et donc les close() suivants ne seront pas appelés.

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

    Informations forums :
    Inscription : Août 2006
    Messages : 3 277
    Par défaut
    Car si une exception est levée dans le finally sur le close, alors cette exception va écraser une éventuelle exception levée dans le try, et donc l'exception initiale, celle qui nous interesse, est perdue.
    Je ne vois pas pourquoi elle serait perdue si on la laisse remonter.

    Pour le coup des catchs que je ne fais pas dans le finally, tu n'a pas tort, mais ta technique n'est pas mieux, car si un problème intervient uniquement sur le close, et bien tu n'auras aucune trace.

  6. #6
    Membre averti
    Inscrit en
    Janvier 2009
    Messages
    46
    Détails du profil
    Informations forums :
    Inscription : Janvier 2009
    Messages : 46
    Par défaut
    Essaye de faire un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try{
       throw new Exception("Exception qu'on veut catcher");
    }
    finally{
       throw new Exception("Exception sur le close");
    }
    Et tu verras que c'est "Exception sur le close" qui va être propagée. L'exception lancée dans le try est tout simplement perdue !!! Alors que c'est elle qui contient le message d'erreur réel.

    Si un problème intervient sur le close comme tu dis, pour moi on s'en fou complétement. Ca n'a strictement aucun impact et ne nécessite pas pour moi d'être loggé. Au niveau du finally, le commit() a déja été réalisée, ou une exception levée. Si la connexion a été perdue entre temps... aucun impact.

  7. #7
    Membre chevronné
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    394
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 394
    Par défaut
    J'ai oublié de te demander quelle version de JAVA tu utilises ? Car en JAVA 7 il y a une nouvelle méthode pour clôturer les ressources, je te laisse lire : http://docs.oracle.com/javase/tutori...urceClose.html

    En gros en java 7 le try a une section avec des parenthèses qu'il n'avait pas avant :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    try( /* déclaration des ressources */ ){
    // utilisation des ressources
    } catch(IOException e){
    // gestion exception
    }
    // en sortie du try les ressources sont closes quoi qu'il arrive
    Romain.

    EDIT : Je t'ai parlé avant de IO Utils, mais pour des ressources JDBC, c'est plutôt DB Utils qu'il faut utiliser : http://commons.apache.org/dbutils/

Discussions similaires

  1. Layout des composants sans utiliser Borland.jdbc
    Par POKOU dans le forum Débuter
    Réponses: 7
    Dernier message: 30/12/2010, 16h40
  2. [MFC] acces a des composants
    Par abignon dans le forum MFC
    Réponses: 7
    Dernier message: 26/03/2004, 12h58
  3. [Kylix] Trouver des composants pour Kylix 3
    Par busy999 dans le forum EDI
    Réponses: 2
    Dernier message: 17/02/2003, 15h01
  4. Réponses: 1
    Dernier message: 26/01/2003, 16h13
  5. Réponses: 1
    Dernier message: 02/01/2003, 13h45

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