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 :

Connection fermée automatiquement ?


Sujet :

JDBC Java

  1. #1
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut Connection fermée automatiquement ?
    Hello,

    J'ai un bout de code qui execute à la chaine une même requête (extraction de lignes de manière aléatoire) sur une même connection (et un même statement).

    voici le worflow simplifié:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    Connection c = getConnection();
    Statement stmt = c.createStatement() ;
     
    String query = getQuery() ;
    for(int i = 0 ; i < n ; i++) {
        ResultSet rs = stmt.executeQuery(query) ;
        while(rs.next()) {
            // do something
        }
        rs.close() ;
    }
    problème: lorsque j'execute la requête a la première itération, tout est OK, mais à la deuxième, je recoit une exception m'indiquant que la connection a été fermée.

    Un petit println(c.isClosed()) me montre qu'en effet, la connection devient fermée après avoir executé la requête pour la première fois...

    Quelqu'un aurait-il une idée de ce que ca pourrait être ? J'utilise le dernier driver JDBC de mysql et je n'ai jusque là jamais rencontré ce type d'erreur.

    Merci d'avance...

  2. #2
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    c'est que le code a appelé close() sur le resultSet ou sur le stmt.

  3. #3
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    Ouai j'aimerai bien que ca soit ca, mais non...

    En tout cas pas explicitement dans mon code: j'utilise un pool de connections (http://www.snaq.net/java/DBPool/), et si au lieu d'utiliser la connection récupérée par getConnection(), j'en crée une nouvelle toute fraiche, mon code tourne sans problème...

  4. #4
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    quelle est la durée de votre traitement par row? Un timeout peut-il en être la cause?

  5. #5
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    J'en doute fortement... Ma requête est simplissime, je récupère 100 lignes sur deux colonnes dans une table sans aucune jointure...

    La connection se ferme juste après le premier appel à stmt.executeQuery(query)... Aucune exception rien (sauf celle m'indiquant que la connection est fermée lorsque j'essai à nouveau d'executer la requête).

    Et encore une fois, si j'utilise une connection nouvellement créee, ou si j'appele à nouveau getConnection() (et donc je récupère une autre connection dans le pool), ca passe nickel...


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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 7 311
    Points : 9 524
    Points
    9 524
    Billets dans le blog
    1
    Par défaut
    Il faudrait avoir le code complet, là, ça restera pure spéculation...
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    Voici une version épurée (sans commentaires, sans print, sans log) du 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
    63
    64
    65
    66
    67
    68
    69
    70
     
    /**
     *
     * @author vince
     */
    public class ComputeHullWorker extends SwingWorker<Integer, Object>
    {
        public static final Logger logger = Logger.getLogger(
                                ComputeHullWorker.class.getCanonicalName());
     
        private final SADB sadb;
        private final HullCreator hullCreator;
     
        public ComputeHullWorker(SADB sadb, HullCreator hullCreator) {
            this.sadb = sadb ;
            this.hullCreator = hullCreator ;
     
            logger.setLevel(SAProperties.instance().logLevel()) ;
        }
     
        @Override
        protected Integer doInBackground()
                throws Exception {
     
            Connection c = sadb.getConnection();
            Statement s = null ;
     
            int dbId = -1 ;
            try {
                c.setAutoCommit(false) ;
                s = c.createStatement() ;
     
                String query = " SELECT mol_x,mol_y FROM CSCoords ORDER BY RAND() LIMIT 100";
     
                List<ConvexHull2D> hulls = new ArrayList<ConvexHull2D>(10);
                for(int i = 0 ; i < 10 ; i++) {
                    List<double[]> coords = new ArrayList<double[]>(subsetsSize) ;
     
                    ResultSet rs = s.executeQuery(query) ;
                    while(rs.next()) {
                        coords.add(new double[]{rs.getDouble(1), rs.getDouble(2)}) ;
                    }
                    rs.close();
     
                    if(coords.size() < 3) {
                        throw new Exception(
                                "Cannot compute convex hull: not enough coordinates found in the database!") ;
                    }
     
                    hulls.add(hullCreator.getHull_(coords)) ;
                }
     
                ConvexHull2D consensus = ConvexHull2D.getAverageHull(hulls, 360);
     
                dbId = sadb.getHullDAO().insertHull(consensus);
     
                c.commit();
            }
            catch(Exception e) {
                logger.log(Level.SEVERE, "Error while computing convex hull", e);
                c.rollback();
                throw e ;
            }
            finally {
                DBUtils.close(c);
            }
     
            return dbId;
        }
    }
    L'ensemble de mes SwingWorkers fonctionnent sur cette base (récupération d'une connection, traitement etc...) sans aucun soucis.

    Autre chose à savoir, ce worker fait partis d'un processus qui execute deux autres SwingWorker avant celui-ci, mais il n'y a aucune intéraction entre eux et leur execution est séquentielle donc je doute que ca ai une quelconque importance...

    Par ailleurs, lorsque je modifie le code ci-dessus et que je remplace juste par l'execution de deux requêtes bidons à la suite, même problème: dès qu'une requête est exectuée, la connection se ferme...

    Ca semble donc être l'objet connection que je récupère qui est corrompu (si j'utilise une connection toute fraiche ca marche), mais aucune idée de pourquoi, et c'est d'autant plus bizard que ca me le fait à chaque execution du programme et toujours pour ce worker là...

  8. #8
    Expert éminent sénior
    Avatar de adiGuba
    Homme Profil pro
    Développeur Java/Web
    Inscrit en
    Avril 2002
    Messages
    13 938
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Java/Web
    Secteur : Transports

    Informations forums :
    Inscription : Avril 2002
    Messages : 13 938
    Points : 23 190
    Points
    23 190
    Billets dans le blog
    1
    Par défaut
    Salut,



    A quoi correspond le code de SADB.getConnection() ?

    Au passage tu devrais aussi utiliser les try/finally pour fermer le ResultSet et le Statement...


    a++

  9. #9
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    sadb.getConnection() me renvoi une connection à la base de donnée courante. En pratique, j'utilise DBPool pour stocker un certain nombre de connections pré-ouvertes.

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    338
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Mars 2008
    Messages : 338
    Points : 402
    Points
    402
    Par défaut
    Peux tu montrer le code de la métode getConnection();
    Peut être c'est un problème de concurrence. ajoute synchronized à la méthode pour voir.

  11. #11
    Expert éminent sénior
    Avatar de tchize_
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Avril 2007
    Messages
    25 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Belgique

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 481
    Points : 48 806
    Points
    48 806
    Par défaut
    il nous faudrait le stacktrace complet et la ligne qui correspond à l'erreur (car on a pas tes numéros de lignes ).

    Est-ce sur le next(), sur le getDouble(), sur le executeQuery() qu'a lieu l'exception?

  12. #12
    Membre habitué
    Inscrit en
    Janvier 2005
    Messages
    491
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 491
    Points : 172
    Points
    172
    Par défaut
    Problème réglé non sans mal:

    Pour mémoire, j'execute 3 SwingWorkers à la suite. Chacun de ces workers récupére une connection dans le pool, l'utilise, et la ferme quand il a terminé. L'execution de ces worker est séquentielle dans le thread appelant: je fait appel à la méthode get() de chacun des worker juste après avoir lancé leur execution.

    Dans mon implémentation initiale, j'avais surchargé la méthode done() de chaque SwingWorker dans laquelle je fermais la connection utilisée durant le traitement.

    Le problème était le suivant: dans thread3, je récupére une connection C du pool, qui se trouve être celle utilisée et fermée (remise dans le pool) par thread2 juste avant.

    Thread3 travail donc dessus, mais grace à un println salvateur, je remarque que la méthode done() se retrouve appelée PENDANT l'execution de thread3 (alors que je pensais que l'appel à get() suffisait à garantir la fin du worker).

    Du coup, ce get() ayant pour but de fermer la connection de thread2, et celle-ci ayant été récupérée entre temps par thread3, je me retrouve avec l'exception décrite plus haut...

    Conclusion: bien lire la doc du SwingWorker et se souvenir que done() est executé dans le Event Dispatch Thread !

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

Discussions similaires

  1. Fenetre qui se ferme automatiquement
    Par ramon.dekker dans le forum Débuter avec Java
    Réponses: 3
    Dernier message: 11/09/2008, 11h31
  2. Fenêtre qui se ferme automatiquement
    Par fred61 dans le forum Dev-C++
    Réponses: 3
    Dernier message: 17/04/2007, 14h32
  3. Comment se connecter à InterNet automatiquement au démarrage de windows
    Par ninj@ dans le forum Dépannage et Assistance
    Réponses: 4
    Dernier message: 24/09/2006, 22h11
  4. faux popup qui se ferme automatiquement
    Par mussara dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 31/03/2006, 15h36
  5. probleme JFrame : ferme automatique l'application
    Par daweed74 dans le forum Agents de placement/Fenêtres
    Réponses: 6
    Dernier message: 17/03/2006, 11h55

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