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 :

Fermeture des PreparedStatements et ORA_01000


Sujet :

JDBC Java

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    Billets dans le blog
    1
    Par défaut Fermeture des PreparedStatements et ORA_01000
    Bonjour,

    J'ai un problème qui est déjà revenu plusieurs fois sur ce forum : j'ai un programme qui rencontre l'erreur ORA-01000: nombre maximum de curseurs ouverts dépassé. Je sais que quand on ouvre un preparedStatement, il faut ensuite le fermer avec sa méthode close(). Et je pense que c'est fait dans l'appli...

    L'application en question permet de lire des fichiers, de les découper en enregistrement, et de mettre chaque enregistrement dans une table. On vient de développer un nouveau type de fichier pour lequel, en fonction de la valeur d'un champ, un enregistrement sera insérer à l'aide de la requête A ou de la requête R. A chaque enregistrement, j'ai donc un test tel que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    if(type = 'A')
    {
    	m_stmt_insert = m_cnx.prepareStatement( m_requeteACH );
    }
    else //type='R'
    {
    	m_stmt_insert = m_cnx.prepareStatement( m_requeteRTD );
    }
    Avec les déclarations suivantes (ailleurs dans la classe, ou dans les classes mères):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    	protected Connection m_cnx;
    	protected PreparedStatement m_stmt_insert = null;
    	private String m_requeteRTD;
    	private String m_requeteACH;
    A la fin de chaque enregistrement, j'ai :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    		if ( m_stmt_insert != null )
    		{
    			m_stmt_insert.close();
    		}
    Tant que la volumétrie en entrée est faible, OK ; dés qu'elle est trop grosse, boum ! Mon nombre de curseurs autorisés par session est de 300, et au bout de 293 enregistrement, ça claque...

    Est-ce que le problème vient des bouts de code mis ici ou est-ce que ça viendrait d'ailleurs ? J'ai lu sur ce forum que des gens avaient aussi eu des soucis avec un close() sans effet, comme si l'objet Oracle n'était pas vraiment fermé.

    Je soupçonne fortement le fait de recréer le preparedStatement à chaque enregistrement (avec m_stmt_insert = m_cnx.prepareStatement( m_requeteRTD ); par exemple). En effet, nous avons d'autres classes, traitant des fichiers similaires, mais la commande m_stmt_insert = m_cnx.prepareStatement( m_requeteAutre ); n'est fait qu'une seule fois (il y a un seul type d'enregistrement, donc on fait ça dans l'initialisation et non à chaque fois)...

    Je suis preneur de toute idée, piste, hypothèse et conseil ! Merci d'avance.

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

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

    Informations forums :
    Inscription : Avril 2007
    Messages : 25 482
    Par défaut
    Le but de l'utilisation d'un preparedstatement, c'est quand même de le réutiliser. Donc pourquoi vous ne créez pas vos deux preparedstatement au débu, vous faites toutes vos insertion et puis vous les cloturez?

  3. #3
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    Billets dans le blog
    1
    Par défaut
    J'avais eu cette idée à l'origine. Je voulais faire un truc comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    m_stmt_insert_ach = m_cnx.prepareStatement( m_requeteACH ); m_stmt_insert_rtd = m_cnx.prepareStatement( m_requeteRTD );
    if(type = 'A')
    {
    	m_stmt_insert = m_stmt_insert_ach;
    }
    else //type='R'
    {
    	m_stmt_insert = m_stmt_insert_rtd;
    }
    pour éviter de dupliquer le code (et parce que m_stmt_insert, variable de classe, est utilisée dans d'autres méthodes).

    [EDIT]
    J'ai essayé hier soir, mais mon binding avec setString (et autres) plante : "java.sql.SQLException: Index de colonne non valide".

    Je vais encore chercher....


    J'ai essayé hier soir, mais mon binding avec setString (et autres) plantait : "java.sql.SQLException: Index de colonne non valide". Cela venait d'une erreur de programmation. Néanmoins, j'ai toujours la même erreur Oracle (qui concerne une table de logs de vue matérialisée....dont je ne maitrise pas les accès dans ma classe....). Cela ne doit pas donc pas venir des mes requêtes d'insertion.

    Je vais encore chercher....
    [/EDIT]

  4. #4
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2009
    Messages
    4 496
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 496
    Billets dans le blog
    1
    Par défaut
    Le problème ne venait effectivement pas de la classe que je venais de développer.

    En fait, la classe faisait appel à une fonction de la classe mère qui était buguée. Depuis près de 4 ans que le système existe, le bug ne s'était jamais produit, les paramètres passés jusqu'à maintenant la faisant rester dans le droit chemin. Il s'avère que je lui ai mis des données différentes en entrée et du coup boumbadaboum!

    On avait :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    if(condition1)
    {
         stmtRechDatVal = m_cnx.prepareStatement( chaine1 );
    }
     
    if(condition2)
    {
         stmtRechDatVal = m_cnx.prepareStatement( chaine2 );
    }
     
    stmtRechDatVal.close()
    et pour la première fois, les deux conditions ont été vérifiées... D'où le nombre de curseurs non contrôlés ^^

    Citation Envoyé par Bktero
    J'ai lu sur ce forum que des gens avaient aussi eu des soucis avec un close() sans effet, comme si l'objet Oracle n'était pas vraiment fermé.
    Ceci ne s'est donc pas vérifié. Un close fait bien son effet.

    Je clos le sujet.

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

Discussions similaires

  1. Ouverture et fermeture des tables
    Par Christophe Charron dans le forum Requêtes
    Réponses: 4
    Dernier message: 31/03/2006, 10h14
  2. [Hibernate][Struts] Fermeture des session hibernate
    Par osopardo dans le forum Hibernate
    Réponses: 2
    Dernier message: 22/08/2005, 17h30
  3. Réponses: 5
    Dernier message: 19/08/2004, 11h11

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