Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Petit problème de curseurs non fermés dans une applie Java sur Oracle par JDBC

16 réponses
Avatar
Trognon Patrice
Bonjour,

J'ai une application Java sur une base Oracle 10g sous linux.
La connection sur la base est assurée par le driver JDBC
d'Oracle de type 4, à savoir j'utilise les jar fournis par
Oracle dans la distribution 10g :
orai18n.jar
ojdbc14.jar

<-----------------Question 1----------------->
Dans mon code j'ai bien vérifié je ferme bien mes curseurs
en appelant la méthode close() du la classe Statement, dans
le doute j'ai aussi invoqué la méthode close() de la
classe ResultSet. Mon application ne fonctionne qu'en select
je n'ai aucunne requete d'INSERT, UPDATE ou DELETE.

Sur un gros traitement je fini par tomber sur un erreur Oracle
m'indiquant que le nombre maximum de curseurs est dépassé :
ORA-01000: nombre maximum de curseurs ouverts dépassé

Comme je ferme bien mes Statement (et meme les ResultSet), je
ne comprends pas d'ou cela vient.

Est ce un bug dans le driver JDBC d'Oracle ?
Est ce un bug au niveau d'Oracle ?

Je ne pense pas que ce soit le cas, tout de même
cela me semble gros !!!

Sinon d'ou cela peut il venir ?

Voila, si quelqu'un est déjà tombé sur le problème et l'a
résolu je suis interessé par tout information.
<-----------------/Question 1----------------->

<-----------------Question 2----------------->
Au passage, seconde question, je voudrais bien loguer dans un
fichier debug.log les requêtes, je travaille uniquement
en PreparedStatement qui sont ensuite bindés par Statement.setX(...).
Comment recupérer le texte de la requete une fois le bind-in
effectué afin de la loguer en clair, pour l'instant je retrouve
dans mon fichier de log les querys avec les ? des paramètres.
<-----------------/Question 1----------------->



--
Cordialement,

Patrice Trognon
http://www.javadevel.com

10 réponses

1 2
Avatar
Gaetan Zoritchak
Trognon Patrice wrote:
Bonjour,

J'ai une application Java sur une base Oracle 10g sous linux.
La connection sur la base est assurée par le driver JDBC
d'Oracle de type 4, à savoir j'utilise les jar fournis par
Oracle dans la distribution 10g :
orai18n.jar
ojdbc14.jar

<-----------------Question 1----------------->
Dans mon code j'ai bien vérifié je ferme bien mes curseurs
en appelant la méthode close() du la classe Statement, dans
le doute j'ai aussi invoqué la méthode close() de la
classe ResultSet. Mon application ne fonctionne qu'en select
je n'ai aucunne requete d'INSERT, UPDATE ou DELETE.

Sur un gros traitement je fini par tomber sur un erreur Oracle
m'indiquant que le nombre maximum de curseurs est dépassé :
ORA-01000: nombre maximum de curseurs ouverts dépassé

Comme je ferme bien mes Statement (et meme les ResultSet), je
ne comprends pas d'ou cela vient.

Est ce un bug dans le driver JDBC d'Oracle ?
Est ce un bug au niveau d'Oracle ?

Je ne pense pas que ce soit le cas, tout de même
cela me semble gros !!!

Sinon d'ou cela peut il venir ?

Voila, si quelqu'un est déjà tombé sur le problème et l'a
résolu je suis interessé par tout information.
<-----------------/Question 1----------------->
Souvenirs, souvenirs...


C'est effectivement une erreur "classique" avec Oracle. Je ne me
souviens plus exactement du problème mais je pense que tu n'as pas de
possibilité d'agir directement sur le nombre de curseurs ouverts. La
première solution est de augmenter le nombre max de curseurs acceptés.
C'est un paramètre de la base. Tu utilises des transactions?

Par ailleurs je te confirme que le driver d'Oracle est un cauchemar
assez délaissé. Depuis des années ils annoncent des développements qui
ne viennent jamais. Désormais j'évite Oracle dans la mesure du possible.

--
Gaetan Zoritchak
Gestion de bug en mode ASP sous java
http://eap.bug-sweeper.fr

Avatar
Trognon Patrice
réponses dans le texte.

Gaetan Zoritchak wrote:
Souvenirs, souvenirs...

C'est effectivement une erreur "classique" avec Oracle. Je ne me
souviens plus exactement du problème mais je pense que tu n'as pas de
possibilité d'agir directement sur le nombre de curseurs ouverts. La
première solution est de augmenter le nombre max de curseurs acceptés.
C'est un paramètre de la base. Tu utilises des transactions?



Ah les mauvais :(.
Bon, je peux augmenter le nombre de curseurs sur la base en effet,
mais bon c'est crade.

Tu n'avais pas essayé de hacker le code du driver JDBC pour solutionner
le problème (enfin si c'est possible (sic)) ?

Et moi qui doutait de mon code !

Par ailleurs je te confirme que le driver d'Oracle est un cauchemar
assez délaissé. Depuis des années ils annoncent des développements qui
ne viennent jamais. Désormais j'évite Oracle dans la mesure du possible.


Ben ouaih, mais la pas trop le choix, ca doit tourner sur de l'Oracle.

--
Cordialement,

Patrice Trognon
http://wwW.javadevel.com

Avatar
Trognon Patrice
Trognon Patrice wrote:

Tu n'avais pas essayé de hacker le code du driver JDBC pour solutionner
le problème (enfin si c'est possible (sic)) ?



ouaih, bon, je viens de regarder dans les sources du driver le close
est codé, donc c'est que c'est buggué. Et on peut pas dire que le code
soit simple simpe.

bon, zut super zut :(

--
Cordialement,

Patrice Trognon
http://wwW.javadevel.com

Avatar
Gaetan Zoritchak
Ah les mauvais :(.
Bon, je peux augmenter le nombre de curseurs sur la base en effet,
mais bon c'est crade.

Tu n'avais pas essayé de hacker le code du driver JDBC pour solutionner
le problème (enfin si c'est possible (sic)) ?

En fait les curseurs ne sont pas gérés au niveau du driver mais dans le

moteur de la base. Un curseur est ouvert pour chaque requête (ou
sous-requête). Un seul appel à une proc ou une requête complexe peut
entraîner l'ouverture de nombreux curseurs. Ils sont refermés lorsque la
transaction se termine. Il faut donc que le paramètre "max open cursors"
soit dimenssionné en fonction du nombre de requêtes parallèles et du
nombre de curseurs par requêtes.

--
Gaetan Zoritchak
Gestion de bug en mode ASP sous java
http://eap.bug-sweeper.fr

Avatar
Trognon Patrice
Gaetan Zoritchak wrote:


Ah les mauvais :(.
Bon, je peux augmenter le nombre de curseurs sur la base en effet,
mais bon c'est crade.

Tu n'avais pas essayé de hacker le code du driver JDBC pour solutionner
le problème (enfin si c'est possible (sic)) ?

En fait les curseurs ne sont pas gérés au niveau du driver mais dans le

moteur de la base. Un curseur est ouvert pour chaque requête (ou
sous-requête). Un seul appel à une proc ou une requête complexe peut
entraîner l'ouverture de nombreux curseurs. Ils sont refermés lorsque la
transaction se termine. Il faut donc que le paramètre "max open cursors"
soit dimenssionné en fonction du nombre de requêtes parallèles et du
nombre de curseurs par requêtes.



mmhhh, étrange j'ai déjà developpé des gros batchs en C en m'appuyant
sur les OCI d'oracle, je fermais bien mes curseurs a partir de mon
code et j'avais pas ce problème :(

il me semble donc bien qu'il y ai un problème dans le code du driver JDBC :(

je vais essayer le driver JDBC s'appuyant sur les OCI navive et je
vais bien voir si le problème persiste.

--
Cordialement,

Patrice Trognon
http://wwW.javadevel.com


Avatar
Trognon Patrice
Trognon Patrice wrote:

Gaetan Zoritchak wrote:


Ah les mauvais :(.
Bon, je peux augmenter le nombre de curseurs sur la base en effet,
mais bon c'est crade.

Tu n'avais pas essayé de hacker le code du driver JDBC pour solutionner
le problème (enfin si c'est possible (sic)) ?

En fait les curseurs ne sont pas gérés au niveau du driver mais dans le

moteur de la base. Un curseur est ouvert pour chaque requête (ou
sous-requête). Un seul appel à une proc ou une requête complexe peut
entraîner l'ouverture de nombreux curseurs. Ils sont refermés lorsque la
transaction se termine. Il faut donc que le paramètre "max open cursors"
soit dimenssionné en fonction du nombre de requêtes parallèles et du
nombre de curseurs par requêtes.



mmhhh, étrange j'ai déjà developpé des gros batchs en C en m'appuyant
sur les OCI d'oracle, je fermais bien mes curseurs a partir de mon
code et j'avais pas ce problème :(

il me semble donc bien qu'il y ai un problème dans le code du driver JDBC
:(

je vais essayer le driver JDBC s'appuyant sur les OCI navive et je
vais bien voir si le problème persiste.



bon, idem avec le driver basé sur les OCI.

a la fin du projet je referais un test en C pour vérifier tout cela
quand meme.

Merci pour tes réponses.

Patrice Trognon.



Avatar
Lionel
Trognon Patrice wrote:
il me semble donc bien qu'il y ai un problème dans le code du driver
JDBC :(


Tu closes bien tes statement dans un finally ?
Tu closes aussi la connexion ?
En cas de boucle, tu réutilises bien le meme PreparedStatement ?
Aucun souci chez moi, pourtant je fais un paquet de requetes.

Pour les ? dans les logs, pas d'autre solution que d'afficher à la main les
paramètres passés à oracle.
Meme si tu regardes passer les requetes directement dans oracle, tu ne
verras pas les valeurs.

Avatar
jpd
Trognon Patrice wrote:
Trognon Patrice wrote:


Gaetan Zoritchak wrote:


Ah les mauvais :(.
Bon, je peux augmenter le nombre de curseurs sur la base en effet,
mais bon c'est crade.

Tu n'avais pas essayé de hacker le code du driver JDBC pour solutionner
le problème (enfin si c'est possible (sic)) ?



En fait les curseurs ne sont pas gérés au niveau du driver mais dans le
moteur de la base. Un curseur est ouvert pour chaque requête (ou
sous-requête). Un seul appel à une proc ou une requête complexe peut
entraîner l'ouverture de nombreux curseurs. Ils sont refermés lorsque la
transaction se termine. Il faut donc que le paramètre "max open cursors"
soit dimenssionné en fonction du nombre de requêtes parallèles et du
nombre de curseurs par requêtes.



mmhhh, étrange j'ai déjà developpé des gros batchs en C en m'appuyant
sur les OCI d'oracle, je fermais bien mes curseurs a partir de mon
code et j'avais pas ce problème :(

il me semble donc bien qu'il y ai un problème dans le code du driver JDBC
:(

je vais essayer le driver JDBC s'appuyant sur les OCI navive et je
vais bien voir si le problème persiste.




bon, idem avec le driver basé sur les OCI.

a la fin du projet je referais un test en C pour vérifier tout cela
quand meme.

Merci pour tes réponses.

Patrice Trognon.

Bonjour,


Peux tu nous fournir ton testcase ? Je viens d'essayer sur base 9iR2
(9.2.0.5)et 10g (10.1.0.3) un petit testcase de stress (ouverture
connexion, creation de statement, lecture resultset, fermeture
resultset, fermeture statement, fermeture connexion), avec leur drivers
jdbc respectif et je n'ai aucuns problemes de curseurs.

Cordialement,
JP




Avatar
Symon
Es tu sur de ne jamais faire ce genre de choses ? On a eu ce problème et
retrouvé du code dans ce goût la dans nos objets d'accès aux données.

PreparedStatement pstmt = conn.prepareStatement(query);

//...

ResultSet rset = pstmt.executeQuery();

while (rset.next()) {

// la belle sous requête qui nous fait perdre
// notre référence sur le premier statement ...
// on ne pourra plus le fermer avant que la
// connexion ne soit fermée et qu'elle cascade
// sur les statement ...
pstmt = conn.prepareStatement();

// puis les close qui vont bien, bien sur

}

A+

Symon

Lionel wrote:
Trognon Patrice wrote:

il me semble donc bien qu'il y ai un problème dans le code du driver
JDBC :(



Tu closes bien tes statement dans un finally ?
Tu closes aussi la connexion ?
En cas de boucle, tu réutilises bien le meme PreparedStatement ?
Aucun souci chez moi, pourtant je fais un paquet de requetes.

Pour les ? dans les logs, pas d'autre solution que d'afficher à la main les
paramètres passés à oracle.
Meme si tu regardes passer les requetes directement dans oracle, tu ne
verras pas les valeurs.





Avatar
Trognon Patrice
réponses dans le texte.

Es tu sur de ne jamais faire ce genre de choses ? On a eu ce problème et
retrouvé du code dans ce goût la dans nos objets d'accès aux données.

PreparedStatement pstmt = conn.prepareStatement(query);

//...

ResultSet rset = pstmt.executeQuery();

while (rset.next()) {

// la belle sous requête qui nous fait perdre
// notre référence sur le premier statement ...
// on ne pourra plus le fermer avant que la
// connexion ne soit fermée et qu'elle cascade
// sur les statement ...
pstmt = conn.prepareStatement();

// puis les close qui vont bien, bien sur

}



Ca non je n'ai pas :)

par contre ce que j'ai c'est ca :

PreparedStatement stmt = conn.prepareStatement(query) ;
ResultSet rset = stmt.executeQuery();
while (rset.next()) {
PreparedStatement stmtDEUX = conn.prepareStatement(query2) ;
ResultSet rsetDEUX = stmtDEUX.executeQuery();
while ( rsetDEUX.next() ) {
}
rsetDEUX.close();
stmtDEUX.close();
}
rset.close();
stmt.close();

Voila, en fait j'ai tracé les open des cursors, et les close, en affichant
la référence de chaque objet alloué et fermé, et j'ai bien
corrélation, chaque statement ouvert est fermé.

D'ou ma question, d'ou la réponse de Gaetan qui me conforte
dans l'impression que bug il y a dans le driver oracle ...

Je vais essayer de reproduire le cas sur un code simple et l'envoyer.

--
Cordialement,

Patrice Trognon
http://wwW.javadevel.com

1 2