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 :

Oracle et problème de fermeture de resultset/statement


Sujet :

JDBC Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Janvier 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 16
    Par défaut Oracle et problème de fermeture de resultset/statement
    Bonjour,

    je suis un utilisateur relativement novice en JDBC et j'ai un problème que je n'arrive pas à résoudre.

    J'ai développé une application JDBC donc et j'obtiens l'erreur oracle : ORA-01000: maximum open cursors exceeded

    Après vérification de l'erreur, c'est que mon nombre de curseur ouvert est trop important.
    Je vérifie mon code, je les ferme tous de suite après utilisation.
    Par contre dans Oracle, ils apparaissent toujours comme ouverts.
    On dirait que le close est sans effet.

    Mon application étant complexe et les appels à JDBC encapsulés dans une classe de gestion des accès à la database, voici le code simple que j'ai essayé pour tester l'effet des close():
    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
    try {
    			Class cOracleDriver;
    			Driver dOracleDriver;
    			cOracleDriver=Class.forName("oracle.jdbc.driver.OracleDriver");
    			dOracleDriver=(Driver) cOracleDriver.newInstance();
    			DriverManager.registerDriver(dOracleDriver);
    			Connection con = DriverManager.getConnection("jdbc:oracle:thin:@guzet.**.net:1521:mydb","user","mdp");
    			Statement st = con.createStatement();
    			ResultSet myRS;
    			myRS = st.executeQuery("select 1 from dual");
    			st.close();
    			myRS.close();
    			System.out.println("endormi");
    			Thread.sleep(30000);
    			System.out.println("reveillé");
    			con.close();
    			System.out.println("endormi");
    			Thread.sleep(30000);
    			System.out.println("reveillé");
    			System.out.println("fin");
    		} catch (Exception e) {
    			// TODO Auto-generated catch block
    			e.printStackTrace();
    		}
    Lors du premier sleep, le curseur est toujours ouvert dans oracle.
    Requête exécutée pour le vérifier :
    SELECT * from v$open_cursor WHERE SID = 29;
    Le numéro de SID est le bon, j'ai vérifié auparavant.

    Lors du second sleep, la connexion est bien fermée, le curseur n'apparait plus.

    J'utilise le driver fournit par Oracle et téléchargé à cette URL:
    http://www.oracle.com/technology/sof.../jdbc9201.html
    C'est la version pour Oracle 9.2.0.8 qui est la version de SGBD qu'on utilise.
    J'utilise le JDK 1.6.
    Les ordres SQL marchent bien quels qu'ils soient, j'ai juste ce problème de curseur qui restent ouverts.

    Après avoir lu les FAQ et cherché sur le net, j'ai rien trouvé pour résoudre ce problème donc si vous pouviez m'aider (même si ce ne sont que des axes de recherche !), je vous en remercie d'avance !

  2. #2
    in
    in est déconnecté
    Membre Expert 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
    Par défaut
    normalement, tous les objets ouverts doivent être fermés dans la clause finally, et ce pour être sûr de les fermer justement ...

    Est ce que ça n'améliore pas les choses ?

    [EDIT] d'ailleurs pour ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    st.close();
    myRS.close();
    c'est dans l'ordre inverse qu'il faut fermer ...
    [/EDIT]

    PS : enlève l'url de ton serveur (ou les login, mot de passe)

  3. #3
    Membre averti
    Inscrit en
    Janvier 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 16
    Par défaut
    Citation Envoyé par in Voir le message
    normalement, tous les objets ouverts doivent être fermés dans la clause finally, et ce pour être sûr de les fermer justement ...

    Est ce que ça n'améliore pas les choses ?

    PS : enlève l'url de ton serveur (ou les login, mot de passe)

    Les logins/mdp ne sont pas les bons (mais j'ai édité l'url quand même ^^)

    J'ai essayé avec un bloc try{}finally{} pour être sûr de les fermer et même résultat

    OButterlin, dans ce cas là, je ne peux pas clore les resultset ou les statements ?
    On ne peut pas avoir une connexion persistante à la BD et fermer des objets liés à cette connexion ?

    Je vais voir du coté d'un pool de connexion mais j'aimerai quand même arriver à clore mes recordset en gardant ma session ouverte. Ca me parait possible et pas illogique.

  4. #4
    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
    Il est tout à fait possible de garder une connexion ouverte et de l'utiliser n fois mais il faut être certain de ne pas en demander une autre sans avoir fermé la précédente...
    Et si tous tes programmes font ça, tu arriveras au nombre max de connexions ...

    Mais franchement, il vaut mieux la fermer après usage et en demander une nouvelle au début du traitement (en même temps, tu éviteras le cas où la transaction s'est fait shooter par une cause externe, timeout par exemple).

    Sinon, peux-tu expliquer un peu plus en détail ce que tu cherches à faire ?

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  5. #5
    Membre averti
    Inscrit en
    Janvier 2005
    Messages
    16
    Détails du profil
    Informations forums :
    Inscription : Janvier 2005
    Messages : 16
    Par défaut
    Pour le gestionnaire de connexion implémenté, pas de problème.
    Il ne se connecte qu'une fois à la base de donnée par session de l'outil. Donc le nombre de connexion n'excède jamais une par utilisateur.
    Le timeout est géré aussi.

    En gros je développe l'outil d'administration d'une application basée sur Oracle. Développement en Java vous l'aurez deviné.

    Sur certaines IHM, j'ai plus d'une dizaine de requêtes à lancer donc clore la connexion puis la relancer, c'est pas top niveau perfos. Surtout que là je suis sur le site mais cette appli va être déployée aux Etats Unis et les temps de connexion sont encore plus génants dans ce cas là.

    Je vais essayer en inversant l'ordre des close (d'abord resultSet puis Statement, meme si d'après la doc, un close du statement clos les resultsets associés).

    Je vais tester ma connexion en ajoutant cette commande : setHoldability (ResultSet.CLOSE_CURSORS_AT_COMMIT )
    voir si ça résoud le problème.

    Si rien ne marche, je me tournerai vers les pools de connexion ma ça m'emballe pas plus que ça pour ce que j'ai à faire...

  6. #6
    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
    A priori, ton problème est plutôt simple...
    Si tu as une connexion par client, créé plusieurs statements ça fonctionnera sans problème...
    N'oublie pas de fermer le statement à la fin de ta méthode quand même...
    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
     
    Statement stmt1 = null;
    PreparedStatement pstmt2 = null;
     
    try
    {
       stmt1 = connection.createStatement();
       pstmt2 = connection.prepareStatement("select * from Table2 where idParent=?");
     
       ResultSet rs1 = stmt1.executeQuery("select * from Table1");
       while ( rs1.next() )
       {
          pstmt2.setInt(1, rs.getInt("ID"));
          ResultSet rs2 = pstmt2.executeQuery();
          while ( rs2.next() )
          {
             ...
          }
       }
    }
    catch (Exception e)
    {
       ...
    }
    finally
    {
       if ( stmt1 != null ) stmt1.close();
       if ( pstmt2 != null ) pstmt2.close();
    }
    Ce genre de chose fonctionne très bien...

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  7. #7
    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
    Il est certain que ton "canal" vers la base de données est issu de Connection, pas de Statement (ou PreparedStatement) ni ResultSet.
    D'ailleurs, tu peux créer plusieurs Statement sur la même connexion et obtenir autant de resultSet.
    Dans ton cas, il faudra fermer la connexion...

    Tu peux (peut-être) passer par un pool de connexions pour accélérer l'acquisition d'une connexion (si le problème vient du temps d'acquisition)

    A+
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

Discussions similaires

  1. JBuilder 2005 et Oracle 9i-> Problème JDBC drive
    Par Devil666 dans le forum JBuilder
    Réponses: 1
    Dernier message: 04/04/2005, 14h14
  2. [TQuery] problème de fermeture
    Par mammistegon dans le forum Bases de données
    Réponses: 5
    Dernier message: 29/01/2005, 18h15
  3. [Thread][socket]Problème de fermeture d'un thread
    Par meda dans le forum Concurrence et multi-thread
    Réponses: 4
    Dernier message: 04/11/2004, 01h03
  4. Problème de fermeture de l'application
    Par SkyDev dans le forum Langage
    Réponses: 2
    Dernier message: 16/06/2004, 02h06
  5. Problème de fermeture de balise <tr>
    Par nuage dans le forum XSL/XSLT/XPATH
    Réponses: 2
    Dernier message: 18/03/2004, 09h55

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