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 :

Problème ! Nombre de curseurs ouverts dépassé


Sujet :

JDBC Java

  1. #1
    Nouveau membre du Club
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Points : 35
    Points
    35
    Par défaut Problème ! Nombre de curseurs ouverts dépassé
    Bonjour à tous

    J'ai un petit souci JDBC avec ORACLE.

    En fait dans un projet JAVA, j'ai un package qui contient que des classes pour les accès à la base de données, toutes ses classes se ressemblent avec celle-ci :
    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
    public class ContentAreaData {
    
        private Statement stmt;
        private ResultSet rset;
        private Connection conn;
        
    
        public Vector <Folders> listeFolders(String caid)  {
            Vector<Folders> resultat = new Vector<Folders>();
            StringBuffer requete ="MaRequete";
            try {
                rset = stmt.executeQuery(requete.toString());
                while (rset.next()) {
                    Folders folderTmp = new Folders(rset);
                    resultat.add(folderTmp);
                }
                rset.close();
            } catch (SQLException e) {
               System.out.println("Erreur de selection "+ e.getMessage());
            }        
            return resultat;
        }
    }
    Elle a trois attributs : ResultSet, Statement et Connexion,
    Le Statement et le Connection sont initialisés dans le constructeur, quand au ResultSet il est initialisé dans les méthodes qui permettent de récupérer des données de la base de données, une fois que j'ai récupéré mes résultats je ferme le ResultSet.

    Mais le problème c'est que j'ai l'impression que le resultSet n'est pas fermé, car quand j'ai beaucoup de requêtes à faire j'ai cette erreur qui sort :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    ORA-01000: Nombre maximum de curseurs ouverts atteint
    Maintenant je ne sais si c'est le statement que je dois fermer aussi, ou bien il n’y'a pas d'autres solutions que d'augmenter le nombre de curseurs dans la config d'Oracle, Alors que si les ResultSets sont bien fermé, je ne doit pas avoir plus de 100 ouverts au même temps.

    Merci de votre aide.
    Cordialement hbellahc

  2. #2
    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,


    Est-ce que tu passes souvent dans le bloc catch ? Car dans ce cas là le ResultSet n'est pas fermé

    Je te conseille fortement d'utiliser des try/finally pour toujours libérer tes ressources au plus tôt...
    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
     
        public Vector <Folders> listeFolders(String caid)  {
            Vector<Folders> resultat = new Vector<Folders>();
            StringBuffer requete ="MaRequete";
            try {
                ResultSet rset = stmt.executeQuery(requete.toString());
                try {
                      while (rset.next()) {
                          Folders folderTmp = new Folders(rset);
                          resultat.add(folderTmp);
                } finally {
                      rset.close();
                }
            } catch (SQLException e) {
               System.out.println("Erreur de selection "+ e.getMessage());
            }        
            return resultat;
        }
    Plus d'info dans la FAQ : Comment libérer proprement les ressources (ou comment utiliser proprement les bloc try/finally) ?

    Plus généralement je te conseille fortement d'utiliser cela pour tous les types de ressources à libérer...



    De plus je te conseille fortement d'éviter d'utiliser ces éléments en tant qu'attribut de classe mais de limiter au maximum leurs scopes. Dans cet exemple le ResultSet n'a pas à être utilisé en dehors de la méthode, alors pourquoi est-il déclaré en dehors...

    Et il y a de forte chance que le problème soit également présent pour les Statement/Connection...

    a++

  3. #3
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    Je ne sais pas si ton erreur vient de là mais il est fortement conseillé de fermer ton ResultSet dans un bloc finally. [EDIT] Ha je sentais bien qu'adiGuba allait me griller, je le sentais ...


    Sinon, 2ème point, Vector est une vieille classe. si tu n'es pas en environnement multithread et que tu veux être au gout du jour utilise plutôt une ArrayList

    Enfin, ceci me paraît (très) bizarre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     rset = stmt.executeQuery(requete.toString());
                while (rset.next()) {
                    Folders folderTmp = new Folders(rset);  // pourquoi parcourir le ResultSet si tu t'en sers pour construire un objet ???
                    ...
    Soit ut parcours le resultSet, soit tu t'en sers pour construire un autre objet, mais là ce que tu fais ne sers à rien et est sûrement la cause de ton problème ...

  4. #4
    Nouveau membre du Club
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Points : 35
    Points
    35
    Par défaut
    Citation Envoyé par in Voir le message

    Soit ut parcours le resultSet, soit tu t'en sers pour construire un autre objet, mais là ce que tu fais ne sers à rien et est sûrement la cause de ton problème ...
    En fait je crée un vecteur d'objets, car le constructeur de Folders permet de créer un objet Folders en utilisant le resultat que je trouve dans le rset.

    Sinon j'ai essayé la solution du try{..} finally{} mais ça ne resoud pas le problème.

  5. #5
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    Citation Envoyé par hbellahc Voir le message
    En fait je crée un vecteur d'objets, car le constructeur de Folders permet de créer un objet Folders en utilisant le resultat que je trouve dans le rset.
    Peux tu nous montrer ce constructeur.

    En tous cas ça ne sert à rien de faire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while(rs.next){ // <-- ça ne sert à rien de parcourir
        new MonObject(rs)
    puisque je suppose que tu parcours le resultset dans le constructeur de folder. ton erreur est dûe au fait que tu essaie de parcourir ton resultset à plusieurs endroits de ton code (dans deux classes en l'occurrence) ... enfin je suppose

  6. #6
    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
    Citation Envoyé par hbellahc Voir le message
    Sinon j'ai essayé la solution du try{..} finally{} mais ça ne resoud pas le problème.
    Est-ce que tu l'a bien généralisé à toutes tes ressources ? Car si le problèmes survient ici il peut être posé par d'autres ressources mal fermées...

    Et tu ne m'a pas répondu : est-ce que tu rentres dans des bloc catch pendant ton application ???

    Citation Envoyé par in Voir le message
    puisque je suppose que tu parcours le resultset dans le constructeur de folder.
    Je pense plutôt qu'il utilise le constructeur pour récupérer les données de la ligne courante... Quelque chose du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Folder(ResultSet rs) {
    	this.name = rs.getString("name");
    	this.id = rs.getInt("id");
    }
    a++

  7. #7
    in
    in est déconnecté
    Membre expérimenté Avatar de in
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    1 612
    Détails du profil
    Informations personnelles :
    Localisation : France, Finistère (Bretagne)

    Informations forums :
    Inscription : Avril 2003
    Messages : 1 612
    Points : 1 718
    Points
    1 718
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Je pense plutôt qu'il utilise le constructeur pour récupérer les données de la ligne courante... Quelque chose du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Folder(ResultSet rs) {
    	this.name = rs.getString("name");
    	this.id = rs.getInt("id");
    }
    Ha ok ... ben ça me semblait bizarre mais présenté comme ça effectivement ça à plus de sens ...

    mea culpa

  8. #8
    Nouveau membre du Club
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Points : 35
    Points
    35
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Est-ce que tu l'a bien généralisé à toutes tes ressources ? Car si le problèmes survient ici il peut être posé par d'autres ressources mal fermées...
    Oui je l'ai fait sur toutes mes méthodes ou j'effectue des requêtes, c'est à dire partout ou j'ai des ResultSet.

    Citation Envoyé par adiGuba Voir le message
    Et tu ne m'a pas répondu : est-ce que tu rentres dans des bloc catch pendant ton application ???
    Il rentre dans le catch si jamais y'a une erreur, mais ça arrive justement dans le cas ou le nombre de curseurs ouverts est atteint.

    Citation Envoyé par adiGuba Voir le message
    Je pense plutôt qu'il utilise le constructeur pour récupérer les données de la ligne courante... Quelque chose du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public Folder(ResultSet rs) {
        this.name = rs.getString("name");
        this.id = rs.getInt("id");
    }
    a++
    Exact : c'est ce que je fais dans mes constructeur.



    Merci en tous cas, je vais essayer de suivre le conseil sur le ResultSet, je le déclare que dans mes fonctions et je vous tiens au courant si ça marche.

    Merci encore

  9. #9
    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
    Citation Envoyé par hbellahc Voir le message
    Oui je l'ai fait sur toutes mes méthodes ou j'effectue des requêtes, c'est à dire partout ou j'ai des ResultSet.
    Fais le également pour les Statement et Connection... Pour être sûr

    a++

  10. #10
    Nouveau membre du Club
    Étudiant
    Inscrit en
    Juillet 2006
    Messages
    42
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2006
    Messages : 42
    Points : 35
    Points
    35
    Par défaut
    Citation Envoyé par adiGuba Voir le message
    Fais le également pour les Statement et Connection... Pour être sûr

    a++
    Bonjour à tous

    Milles merci les amis (adiGuba et in) ça marche super bien, en fait j'ai fait ce que tu m'as proposé adiGuba, mes classes ressemblent à celle-ci maintenant
    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
     
    public class ContentAreaData {
     
     
        private Connection conn;
     
     
        public Vector <Folders> listeFolders(String caid)  {
        Statement stmt=null;
        ResultSet rset=null;
        Vector<Folders> resultat = new Vector<Folders>();
        StringBuffer requete = new StringBuffer("SELECT * "
                + "FROM KWEB_FOLDERS " + "WHERE PARENT_ID=0 " + "AND CAID="
                + caid);
        try {
            stmt = conn.createStatement();
            rset = stmt.executeQuery(requete.toString());
            try {
     
                while (rset.next()) {
                    Folders folderTmp = new Folders(rset);
                    resultat.add(folderTmp);
                }
            }finally{
                if (rset!=null) rset.close();
                if (stmt!=null) stmt.close();
            }            
        } catch (SQLException e) {
            logger.warn("Erreur de selection "+ e.getMessage());
            System.out.println("Erreur de selection "+ e.getMessage());
        }        
        return resultat;
        }
    }
    Et ça marche super bien, le nombre de curseurs ouverts reste le même pendant toute l'exécution de mes actions sur l'application.

    Pour ceux ça intéresse, j'ai trouvé une fonction qui permet d'afficher justement le nombre de curseurs ouverts :

    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
    public static int getCurrentOpenCursors(Connection conn) {
                PreparedStatement psQuery = null;
                ResultSet rs = null;
                
                int cursors = -1;
                try {
                  String sqlQuery = "select count(*) AS COUNT from v$open_cursor where user_name like 'NOM DE L'utilsateur '";
                  psQuery = conn.prepareStatement(sqlQuery);
                  rs = psQuery.executeQuery();
                  
                  if (rs.next()) {
                    cursors = rs.getInt("COUNT");
                  }
                } catch (SQLException e) {
                  System.out.println("SQLException in getCurrentOpenCursors(Connection conn): "+e);
                } finally {
                  try {
                    if (rs != null) {rs.close();}
                    if (psQuery != null) {psQuery.close();}
                  }
                  catch (SQLException ex)  {
                    System.out.println("A SQLException error has occured in getCurrentOpenCursors(Connection conn): " + ex.getMessage());
                    ex.printStackTrace();
                  }
                }
                return cursors;
              }
    et aussi comme j'avais beaucoup de classes à modifier, j'ai crée un template pour aller plus vite (pour les gens qui utilisent eclipse ou netbeans):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    try {
        ${line_selection}${cursor}
    } finally {
        if (rset!=null)
            rset.close();
        if (stmt!=null)
           stmt.close();
    }
    Pour l'utiliser il faut la crée comme indiqué sur ce lien http://java.developpez.com/faq/eclip...creerTemplates

    Ensuite Alt+Ctrl+z et choisir le nom que vous avez donné à votre template.

    Voila merci à tous en tous cas.
    Cordialement hbellahc

  11. #11
    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
    Juste une remarque : il est possible d'englober les bloc try/catch afin de bien séparer chaque ressource et d'éviter les vérifications de la nullité :
    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
    	public Vector<Folders> listeFolders(String caid) {
    		Vector<Folders> resultat = new Vector<Folders>();
    		StringBuffer requete = new StringBuffer("SELECT * "
    				+ "FROM KWEB_FOLDERS " + "WHERE PARENT_ID=0 " + "AND CAID="
    				+ caid);
    		try {
    			Statement stmt = conn.createStatement();
    			try {
    				ResultSet rset = stmt.executeQuery(requete.toString());
    				try {
    					while (rset.next()) {
    						Folders folderTmp = new Folders(rset);
    						resultat.add(folderTmp);
    					}
    				} finally {
    					rset.close();
    				}
    			} finally {
    				stmt.close();
    			}
    		} catch (SQLException e) {
    			// logger.warn("Erreur de selection "+ e.getMessage());
    			System.out.println("Erreur de selection " + e.getMessage());
    		}
    		return resultat;
    	}
    Perso je préfère (mais bon on est d'accord cela n'est plus qu'une question de goût )

    a++

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

Discussions similaires

  1. [Doctrine] ORA-0100 nombre maximum de curseurs ouverts dépassé :
    Par Tyra3l dans le forum ORM
    Réponses: 5
    Dernier message: 02/07/2011, 22h50
  2. ORA-01000: nombre maximum de curseurs ouverts dépassé
    Par opensource dans le forum Débuter
    Réponses: 3
    Dernier message: 20/04/2011, 13h30
  3. ORA-01000: nombre maximum de curseurs ouverts dépassé
    Par ouadie99 dans le forum Accès aux données
    Réponses: 6
    Dernier message: 01/09/2008, 10h03
  4. Réponses: 7
    Dernier message: 02/07/2008, 14h17
  5. [Oracle10g Spatial] Problème : Trop de curseurs ouverts
    Par NeraOne dans le forum Administration
    Réponses: 7
    Dernier message: 15/05/2007, 12h12

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