Bonjour à tous,
nous utilisons Hibernate au travail pour un programme comprenant un front et un back-end.
Le back-end se connecte à deux bases distinctes (une Oracle et une Sybase).
Nous avons malheureusement des problèmes avec la base Oracle.
En effet les DBA nous ont averti d'un trop grand nombre de connexions restant ouvertes à la base de données (nous utilisions alors le pool de connection builtin d'Hibernate). Nous sommes donc passés à l'utilisation de c3p0 pour qu'il gère correctement le pool.
Je vais vous mettre directement la config d'hibernate / c3p0:
Le problème est donc comme je l'ai dis plus haut qu'Hibernate laisserait des connexions à la base de données ouvertes, pourtant c3p0 est configuré pour gérer un pool de [0; 10] connexions ouvertes, avec un timeout réglé à une minute pour les release plus rapidement.
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
30
31
32
33 <?xml version='1.0' encoding='utf-8'?> <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"> <hibernate-configuration> <session-factory> <!-- Database connection settings --> <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <property name="connection.url">jdbc:oracle:thin:@url</property> <property name="connection.username">username</property> <property name="connection.password">password</property> <!-- Database connection pool --> <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <property name="c3p0.min_size">0</property> <property name="c3p0.max_size">10</property> <property name="c3p0.timeout">60</property> <property name="c3p0.max_statements">0</property> <property name="c3p0.idle_test_period">60</property> <property name="c3p0.acquire_increment">1</property> <property name="hibernate.connection.aggressive_release">true</property> <!-- This is for debug purpose only --> <property name="c3p0.unreturnedConnectionTimeout">60</property> <property name="c3p0.debugUnreturnedConnectionStackTraces">true</property> <property name="org.apache.commons.logging.Log">org.apache.commons.logging.impl.Log4JLogger</property> <property name="dialect">org.hibernate.dialect.OracleDialect</property> <property name="current_session_context_class">thread</property> <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> <mapping ... /> </session-factory> </hibernate-configuration>
Tout à l'air de bien se passer pendant quelques heures, et le problème reviens à nouveau...
J'ai donc regardé dans les log du backend et voila une erreur qui est lancé des centaines de fois:
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 INFO: Illegal access: this web application instance has been stopped already. Could not load oracle.net.ns.Message11. The eventual following stack trace is caused by an error thrown for debugging purposes as well as to attempt to terminate the thread which caused the illegal access, and has no functional impact. java.lang.IllegalStateException at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1273) at org.apache.catalina.loader.WebappClassLoader.loadClass(WebappClassLoader.java:1233) at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319) at java.lang.Class.forName0(Native Method) at java.lang.Class.forName(Class.java:164) at oracle.net.ns.NetException.<init>(Unknown Source) at oracle.net.ns.Packet.receive(Unknown Source) at oracle.net.ns.NSProtocol.connect(Unknown Source) at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:858) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:268) at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:441) at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801) at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134) at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182) at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171) at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137) at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014) at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32) at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810) at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)Je précise que tout fonctionne vraiment correctement pendant un long moment et puis ça commence à se crasher petit à petit, y compris la base elle même à laquelle on ne peut plus se connecter tant qu'on n'a pas tué tomcat qui héberge l'application (plus de place dispo sur Oracle pour une nouvelle connexion).
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 WARN: com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask@677154 -- Acquisition Attempt Failed!!! Clearing pending acquires. While trying to acquire a needed new resource, we failed to succeed more than the maximum number of allowed acquisition attempts (30). Last acquisition attempt exception: java.lang.NullPointerException at oracle.sql.CharacterSet.make(CharacterSet.java:441) at oracle.jdbc.driver.DBConversion.init(DBConversion.java:152) at oracle.jdbc.driver.DBConversion.<init>(DBConversion.java:116) at oracle.jdbc.driver.T4CConnection.connect(T4CConnection.java:892) at oracle.jdbc.driver.T4CConnection.logon(T4CConnection.java:268) at oracle.jdbc.driver.PhysicalConnection.<init>(PhysicalConnection.java:441) at oracle.jdbc.driver.T4CConnection.<init>(T4CConnection.java:165) at oracle.jdbc.driver.T4CDriverExtension.getConnection(T4CDriverExtension.java:35) at oracle.jdbc.driver.OracleDriver.connect(OracleDriver.java:801) at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:134) at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:182) at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:171) at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:137) at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1014) at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:32) at com.mchange.v2.resourcepool.BasicResourcePool$AcquireTask.run(BasicResourcePool.java:1810) at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:547)
Pour plus d'infos je vous montre le schéma de code Java qui est toujours utilisé pour faire des accès à la base de données via Hibernate, peut-être y a t il une coquille dedans et c'est le bout de code qui oublierais de fermer les connexions dans certains cas ?
J'utilise la classe SessionManager que j'ai trouvé dans la doc hibernate: https://www.hibernate.org/238.html ou via google cache car le site n'a pas l'air de répondre ce matin...
et nous l'utilisons ainsi
J'aurai vraiment besoin d'aide car je suis totalement perdu sur la cause de ces connexions fantômes qui restent en vie alors qu'hibernate/c3p0 devrait les couper quand il n'en a plus besoin
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 SessionManager mgr = new SessionManager(HibernateUtil.getSessionFactory()); mgr.runSession(new DBAction() { public void run(final Session session) throws HibernateException { Person foo= session.createQuery("select p from Person p where p.name = 'foo'").uniqueResult(); // do something } });.
Merci d'avances à tous![]()
Partager