Oracle de connexion pas de clôture dans l'Application Java
J'ai une connexion de fuite dans certaines anciennes applications web Java qui n'utilisent pas le regroupement de connexion.
En essayant de trouver la fuite est difficile, parce que ÇA ne va pas m'accorder l'accès à v$session SELECT Count(*) FROM v$session;
Donc à la place je suis en train de déboguer avec le Système.des relevés. Même après la fermeture de la connexion conn.close();
quand j'ai l'impression conn pour le fichier journal du Système, il me donne le lien nom de l'objet.
try {
Connection conn;
conn.close()
}
catch (SQLException e) { }
finally {
if (conn != null) {
try {
System.out.println("Closing the connection");
conn.close();
}
catch (Exception ex)
{
System.out.println("Exception is " + ex);
}
}
}
//I then check conn and it is not null and I can print the object name.
if (conn != null) {
System.out.println("Connection is still open and is " + conn);
}
cependant, si j'ajoute également conn = null;
ci-dessous la conn.close();
déclaration de la connexion semble maintenant fermé. Donc ma question c'est est-ce conn.close(); en fait, la libération de ma connexion ou dois-je aussi faire nulle pour vraiment libérer de ma connexion. Comme je l'ai dit, c'est vraiment dur pour moi de déterminer si la connexion est effectivement libéré sans être en mesure d'interroger v$session. Est-il un bout de code java qui peut me donner mes connexions ouvertes??
C'est probablement d'enseignement à ce point parce que j'ai l'intention de revoir ces applications pour utiliser le regroupement de connexion mais je suis à la recherche d'un rapide bandaid pour l'instant.
- Je suppose que c'est un peu tiré par les cheveux, mais si vous êtes déclarant
conn
à l'intérieur de latry
bloquer ensuite, il est hors de portée par la suite, et aussi dans lefinally
bloc. Encore, je me demande si vous avez une variable de classe que vous êtes à la répétition, et peut-être que quelque part, l'observation est la rupture et en laissant une fuite derrière. - vous avez raison... dans mon code, elle est déclarée à l'extérieur de l'essayer.
- "semble fermée"?
Vous devez vous connecter pour publier un commentaire.
La partie importante de la clôture est ce qui se passe sur le côté de la base de données. C'est le SGBD qui a pour fermer la connexion. L'appel de la méthode close() est ce que communique le message à la base de données de fermer la connexion.
La configuration de la connexion à la valeur null n'est pas instruire SGBDR rien à faire.
Même logique s'applique à ResultSet, qui est un curseur sur le côté de la base de données, et de la Déclaration. Vous avez besoin de fermer ceux dans les différents blocs try/catch dans le bloc finally de la méthode qui les a créés, dans l'ordre inverse de leur création. Sinon vous verrez des erreurs à propos de "Max curseurs dépassé".
Réglage de la conn null seulement rompt le lien de référence vers l'objet de connexion, et n'a aucune influence sur la connexion de l'ouvrir ou pas. Si la connexion est toujours ouverte alors la connexion sera toujours appelé à partir de l'intérieur du pilote JDBC/pool de connexion etc...
Définition d'une variable à la valeur null est plus révélateur que le garbage collector que c'est ok pour nettoyer l'objet d'origine quand il veut qu'autre chose.
Comme les autres disent, vous avez deux concepts différents ici: fermeture de la connexion et de suivi de la connexion dans une variable.
Pour fermer la connexion, appel
conn.close()
. Cette ne définir la variable conn à null. Vous pouvez tester si la connexion est ouverte avecconn.isClosed()
.Si vous n'avez pas soin de suivre le lien dans votre code, vous ne pouvez
conn = null
. Cette ne pas immédiatement fermer la connexion. Je crois que la connexion sera fermée automatiquement, basée sur le JDBC la documentation :Si vous choisissez d'aller dans cette voie, sachez que le garbage collector peut pas fermer votre connexion aussi rapidement que vous le souhaitez, et vous pouvez avoir ce qui semble être une fuite de ressources; réservé verrous de base de données ne sera pas libéré jusqu'à ce que la connexion est des ordures collectées. Certains pilotes (je ne sais pas si oracle est l'un) imposer une limite maximale pour le nombre de connexions qui peuvent exister à un moment, si en laissant ouverte connexions peuvent également causer des défaillances de se connecter, plus tard dans le programme.
Connexion fuites sont une meilleure. Je pense qu'une bonne stratégie consiste à envelopper l'obtention et la libération des connexions dans un couple de fonctions et de toujours obtenir et de publier vos connexions par le biais de ces fonctions. Ensuite, vous pouvez avoir ces fonctions de maintenir une liste de toutes les connexions ouvertes, et de faire une trace de la pile sur l'appelant de l'allocation de fonction. Alors un écran qui affiche une liste de toutes les connexions ouvertes et d'où ils venaient. Exécuter ce dans un environnement de test et de courir à l'aide d'un tas d'écrans, puis la sortie de tout si toutes les connexions DOIVENT fermer, puis ouvrir l'écran qui montre ouvrir connectoins, et le méchant doit être révélé.
Mon explication ici est une supposition éclairée.
Comme une pratique, j'ai toujours set conn=null après la clôture. Je crois que quand vous ne conn.close() vous dites que le garbage collector qu'il est prêt à être nettoyée. Toutefois, il sera à la collecte des ordures processus pour déterminer à quel moment le faire.
Aussi vous pouvez modifier votre
à
..
Est-il un bout de code Java qui peut me donner mes connexions ouvertes?
Juste un rapide deviner, en supposant que vous utilisez Oracle.
Sugession: Pourquoi ne pas vous installer jboss et configurer le groupement de connexions par là?