Concernant l'anomalie 561
Hello, Je pense avoir corrigé cette anomalie : http://nuiton.org/issues/show/561 En fait l'utilisation du ConnectionProvider fournit par hibernate (org.hibernate.connection.DriverManagerConnectionProvider) pose un problème de gestion des connections fermées [0]. En effet on met dans le pool lorsqu'on ferme la connection (au niveau de l'api d'hibernate). En fait la connection n'est pas fermée (au niveau JDBC). Le problème c'est que l'on ne vérifie pas si cette connection n'a pas été fermée au niveau JDBC et donc on peut mettre dans le pool une connection fermée et donc non utilisable ensuite. J'ai écrit une nouvelle version de la classe de base (org.nuiton.topia.framework.TopiaConnectionProvider). (j'ai pas pu étendre celle d'hibernate vu que tout est en private sans aucun accesseur (bouh!)) donc un petit fork nécessaire. Pour les curieux mon provider est ici : [1] Pour ceux qui ont eu le problème il faudrait essayer ce provider, et bien s'assurer qu'hibernate l'utilise (je pense à jboss qui pourrait faire des siennes et utiliser une DataSource ?). A vos réactions ;) et bon tests. [0] http://www.docjar.com/docs/api/org/hibernate/connection/DriverManagerConnect... [1] http://svn.nuiton.org/svn/topia/trunk/topia-persistence/src/main/java/org/nu... -- Tony Chemit -------------------- tél: +33 (0) 2 40 50 29 28 email: chemit@codelutin.com http://www.codelutin.com
On Thu, 14 Apr 2011 14:47:11 +0200 Tony Chemit <chemit@codelutin.com> wrote:
Hello,
Je pense avoir corrigé cette anomalie : http://nuiton.org/issues/show/561
En fait l'utilisation du ConnectionProvider fournit par hibernate (org.hibernate.connection.DriverManagerConnectionProvider) pose un problème de gestion des connections fermées [0].
Ceci vaut pour la version 3.3.2 (celle de Topia) mais aussi pour la dernière version [2]...
En effet on met dans le pool lorsqu'on ferme la connection (au niveau de l'api d'hibernate). En fait la connection n'est pas fermée (au niveau JDBC).
Le problème c'est que l'on ne vérifie pas si cette connection n'a pas été fermée au niveau JDBC et donc on peut mettre dans le pool une connection fermée et donc non utilisable ensuite.
J'ai écrit une nouvelle version de la classe de base (org.nuiton.topia.framework.TopiaConnectionProvider).
(j'ai pas pu étendre celle d'hibernate vu que tout est en private sans aucun accesseur (bouh!)) donc un petit fork nécessaire.
Pour les curieux mon provider est ici : [1]
Pour ceux qui ont eu le problème il faudrait essayer ce provider, et bien s'assurer qu'hibernate l'utilise (je pense à jboss qui pourrait faire des siennes et utiliser une DataSource ?).
A vos réactions ;) et bon tests.
[0] http://www.docjar.com/docs/api/org/hibernate/connection/DriverManagerConnect...
[1] http://svn.nuiton.org/svn/topia/trunk/topia-persistence/src/main/java/org/nu...
[2] https://github.com/hibernate/hibernate-core/blob/master/hibernate-core/src/m... -- Tony Chemit -------------------- tél: +33 (0) 2 40 50 29 28 email: chemit@codelutin.com http://www.codelutin.com
On Thu, 14 Apr 2011 14:53:53 +0200 Tony Chemit <chemit@codelutin.com> wrote:
Ceci vaut pour la version 3.3.2 (celle de Topia) mais aussi pour la dernière version [2]...
Youhou, si c bien ca le probleme c super, je pense meme qu'il faudrait leur envoyer le patch pour eviter que d'autre se fasse avoir comme nous. Y'a plus qu'a tester. Par contre, je me demande qui peut bien ferme la connexion ? L'application (mais ou ?) ou la base de données apres un certain temps (timeout) pour le code j'aurais bien vu a la place de """ // before getting any connection, make sure there is not a closed // connection in pool, if so then remove them from the pool Iterator<?> itr = pool.iterator(); while (itr.hasNext()) { Connection conn = (Connection) itr.next(); if (conn.isClosed()) { // this connection is closed!, remove it itr.remove(); if (log.isDebugEnabled()) { log.debug("Remove already closed connection from pool " + connection); } } } // try to use a connection from the pool (if any) if (!pool.isEmpty()) { int last = pool.size() - 1; if (log.isTraceEnabled()) { log.trace("using pooled JDBC connection, pool size: " + last); } connection = pool.remove(last); } } """ plutot une version qui verifie juste avant de renvoyer, ca evite de devoir faire le parcours de tout le pool a chaque demande de connexion: """ // try to use a connection from the pool (if any) while (!pool.isEmpty() && connection == null) { int last = pool.size() - 1; if (log.isTraceEnabled()) { log.trace("using pooled JDBC connection, pool size: " + last); } connection = pool.remove(last); if (connection.isClosed()) { // this connection is closed!, don't use it connection = null; if (log.isDebugEnabled()) { log.debug("Remove already closed connection from pool " + connection); } } } } """ -- Benjamin POUSSIN -------------------- tél: +33 (0) 2 40 50 29 28 email: poussin@codelutin.com http://www.codelutin.com
On Fri, 15 Apr 2011 02:48:24 +0200 Benjamin POUSSIN <poussin@codelutin.com> wrote:
On Thu, 14 Apr 2011 14:53:53 +0200 Tony Chemit <chemit@codelutin.com> wrote:
Ceci vaut pour la version 3.3.2 (celle de Topia) mais aussi pour la dernière version [2]...
Youhou, si c bien ca le probleme c super, je pense meme qu'il faudrait leur envoyer le patch pour eviter que d'autre se fasse avoir comme nous.
Y'a plus qu'a tester. Par contre, je me demande qui peut bien ferme la connexion ? L'application (mais ou ?) ou la base de données apres un certain temps (timeout) Pascal (IRD) a testé hier toute l'après-midi et tout va mieux :)
plutot une version qui verifie juste avant de renvoyer, ca evite de devoir faire le parcours de tout le pool a chaque demande de connexion: Oui bonne idée j'applique :)
""" // try to use a connection from the pool (if any)
while (!pool.isEmpty() && connection == null) { int last = pool.size() - 1; if (log.isTraceEnabled()) { log.trace("using pooled JDBC connection, pool size: " + last); }
connection = pool.remove(last); if (connection.isClosed()) {
// this connection is closed!, don't use it connection = null;
if (log.isDebugEnabled()) { log.debug("Remove already closed connection from pool " + connection); } } } } """
-- Tony Chemit -------------------- tél: +33 (0) 2 40 50 29 28 email: chemit@codelutin.com http://www.codelutin.com
On Fri, 15 Apr 2011 02:48:24 +0200 Benjamin POUSSIN <poussin@codelutin.com> wrote:
On Thu, 14 Apr 2011 14:53:53 +0200 Tony Chemit <chemit@codelutin.com> wrote:
Ceci vaut pour la version 3.3.2 (celle de Topia) mais aussi pour la dernière version [2]...
Youhou, si c bien ca le probleme c super, je pense meme qu'il faudrait leur envoyer le patch pour eviter que d'autre se fasse avoir comme nous.
Y'a plus qu'a tester. Par contre, je me demande qui peut bien ferme la connexion ? L'application (mais ou ?) ou la base de données apres un certain temps (timeout) Le provider est fermé par la org.hibernate.impl.SessionFactoryImpl dans la méthode close.
pour le code j'aurais bien vu a la place de """ // before getting any connection, make sure there is not a closed // connection in pool, if so then remove them from the pool
Iterator<?> itr = pool.iterator(); while (itr.hasNext()) { Connection conn = (Connection) itr.next(); if (conn.isClosed()) {
// this connection is closed!, remove it itr.remove();
if (log.isDebugEnabled()) { log.debug("Remove already closed connection from pool " + connection); } } }
// try to use a connection from the pool (if any)
if (!pool.isEmpty()) { int last = pool.size() - 1; if (log.isTraceEnabled()) { log.trace("using pooled JDBC connection, pool size: " + last); }
connection = pool.remove(last); } } """
plutot une version qui verifie juste avant de renvoyer, ca evite de devoir faire le parcours de tout le pool a chaque demande de connexion:
""" // try to use a connection from the pool (if any)
while (!pool.isEmpty() && connection == null) { int last = pool.size() - 1; if (log.isTraceEnabled()) { log.trace("using pooled JDBC connection, pool size: " + last); }
connection = pool.remove(last); if (connection.isClosed()) {
// this connection is closed!, don't use it connection = null;
if (log.isDebugEnabled()) { log.debug("Remove already closed connection from pool " + connection); } } } } """
-- Tony Chemit -------------------- tél: +33 (0) 2 40 50 29 28 email: chemit@codelutin.com http://www.codelutin.com
Le Thu, 14 Apr 2011 14:47:11 +0200, Tony Chemit <chemit@codelutin.com> a écrit :
Hello,
Je pense avoir corrigé cette anomalie : http://nuiton.org/issues/show/561
Excellent ! Ca va me retirer une grosse épine du pied, et je ne pense pas être le seul ! [...]
Pour ceux qui ont eu le problème il faudrait essayer ce provider, et bien s'assurer qu'hibernate l'utilise (je pense à jboss qui pourrait faire des siennes et utiliser une DataSource ?).
Je vais tester qu'il le prenne bien dans Sandra, par contre je n'ai jamais réussi à reproduire le bug sur ma machine, on saura si ça à marché seulement quand ce sera déployé en prod :S
A vos réactions ;) et bon tests.
Well done ! -- Letellier Sylvain letellier@codelutin.com
participants (3)
-
Benjamin POUSSIN -
letellier -
Tony Chemit