2014-08-27 3 views
0

Может ли кто-нибудь помочь мне решить эту ситуацию? У меня есть Tomcat и простое приложение JSF: https://github.com/gooamoko/jsfbilling/. Когда я запускаю приложение на Tomcat, он работает нормально, но после нескольких запросов (например, 10 страниц быстрого обновления) возникает исключение can't open connection. Я думаю, это нормально, но где ошибка?Похоже, что Hibernate превышает лимит связи

В файле конфигурации hibernate.cfg.xml

<?xml version='1.0' encoding='UTF-8'?> 
<!DOCTYPE hibernate-configuration PUBLIC 
      "-//Hibernate/Hibernate Configuration DTD 3.0//EN" 
      "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
    <session-factory> 
     <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property> 
     <property name="connection.driver_class">org.postgresql.Driver</property> 
     <property name="connection.url">jdbc:postgresql://localhost:5432/netstat</property> 
     <property name="connection.username">netstat</property> 
     <property name="connection.password">netstat</property> 

     <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property> 

     <!-- configuration pool via c3p0 --> 
     <property name="c3p0.min_size">5</property> 
     <property name="c3p0.max_size">100</property> 
     <property name="c3p0.max_statements">200</property> 
     <property name="c3p0.timeout">600</property> <!-- seconds --> 

     <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property> 
     <property name="current_session_context_class">thread</property> 
     <property name="hibernate.show_sql">false</property> 
     <property name="hibernate.hbm2ddl.auto">update</property> 
     <!-- Mapping classes --> 
     <mapping class="ru.gooamoko.model.Group" /> 
     <mapping class="ru.gooamoko.model.Host" /> 
     <mapping class="ru.gooamoko.model.Traffic" /> 
     <mapping class="ru.gooamoko.model.DailyTraffic" /> 

    </session-factory> 
</hibernate-configuration> 

или в Java classess

package ru.gooamoko.dao; 

import org.hibernate.SessionFactory; 
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 
import org.hibernate.cfg.Configuration; 
import org.hibernate.service.ServiceRegistry; 

public class HibernateProvider { 
    private static SessionFactory factory; 
    private static ServiceRegistry registry; 

    public static SessionFactory getSessionFactory() { 
     Configuration configuration = new Configuration(); 
     configuration.configure(); 
     registry = new StandardServiceRegistryBuilder().applySettings(
       configuration.getProperties()).build(); 
     factory = configuration.buildSessionFactory(registry); 
     return factory; 
    } 

} 


package ru.gooamoko.dao; 

import org.hibernate.Session; 
import org.hibernate.SessionFactory; 

public class GenericDao { 

    private SessionFactory factory; 
    protected Session session; 

    protected void begin() { 
     session = factory.getCurrentSession(); 
     session.beginTransaction(); 
    } 

    protected void commit() { 
     if (session.isOpen()) { 
      session.getTransaction().commit(); 
     } 
    } 

    protected void rollback() { 
     if (session.isOpen()) { 
      session.getTransaction().rollback(); 
     } 
    } 

    public GenericDao() { 
     this.factory = HibernateProvider.getSessionFactory(); 
    } 
} 

В котом журнал я вижу этот

27-Aug-2014 15:06:24.559 WARNING [C3P0PooledConnectionPoolManager[identityToken->1hge12w9467h4hm1tfa5tj|3b40a97d]-HelperThread-#2] com.mchange.v2.resourcepool.BasicResourcePool.forceKillAcquires Having failed to acquire a resource, [email protected] is interrupting all Threads waiting on a resource to check out. Will try again in response to new client requests. 
27-Aug-2014 15:06:24.563 WARNING [C3P0PooledConnectionPoolManager[identityToken->1hge12w9467h4hm1tfa5tj|3b40a97d]-HelperThread-#2] com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run com[email protected]628977a2 -- 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: 
org.postgresql.util.PSQLException: ?????: ?????????? ????? ??????????? ??????????????? ??? ??????????? ????????????????? (?? ??? ??????????) 
    at org.postgresql.core.v3.ConnectionFactoryImpl.readStartupMessages(ConnectionFactoryImpl.java:572) 
    at org.postgresql.core.v3.ConnectionFactoryImpl.openConnectionImpl(ConnectionFactoryImpl.java:177) 
    at org.postgresql.core.ConnectionFactory.openConnection(ConnectionFactory.java:64) 
    at org.postgresql.jdbc2.AbstractJdbc2Connection.<init>(AbstractJdbc2Connection.java:136) 
    at org.postgresql.jdbc3.AbstractJdbc3Connection.<init>(AbstractJdbc3Connection.java:29) 
    at org.postgresql.jdbc3g.AbstractJdbc3gConnection.<init>(AbstractJdbc3gConnection.java:21) 
    at org.postgresql.jdbc4.AbstractJdbc4Connection.<init>(AbstractJdbc4Connection.java:31) 
    at org.postgresql.jdbc4.Jdbc4Connection.<init>(Jdbc4Connection.java:24) 
    at org.postgresql.Driver.makeConnection(Driver.java:393) 
    at org.postgresql.Driver.connect(Driver.java:267) 
    at com.mchange.v2.c3p0.DriverManagerDataSource.getConnection(DriverManagerDataSource.java:146) 
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:195) 
    at com.mchange.v2.c3p0.WrapperConnectionPoolDataSource.getPooledConnection(WrapperConnectionPoolDataSource.java:184) 
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool$1PooledConnectionResourcePoolManager.acquireResource(C3P0PooledConnectionPool.java:200) 
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquire(BasicResourcePool.java:1086) 
    at com.mchange.v2.resourcepool.BasicResourcePool.doAcquireAndDecrementPendingAcquiresWithinLockOnSuccess(BasicResourcePool.java:1073) 
    at com.mchange.v2.resourcepool.BasicResourcePool.access$800(BasicResourcePool.java:44) 
    at com.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask.run(BasicResourcePool.java:1810) 
    at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:648) 

Как и где следует Я исправляю закрытые открытые соединения?

Спасибо, что тратили свое время на меня.

+1

Может быть, потому, что вы не закрываете соединения с базой данных? В любом случае вы должны использовать пул соединений. – Andremoniy

+0

Пожалуйста, не связывайтесь с кодом. Включите наиболее важные части этого вопроса непосредственно в свой вопрос. Если вы удалите этот проект github или содержимое страницы будет изменено в будущем, эти ссылки не будут полезны другим читателям. – BackSlash

+0

@BackSlash Ok. Я буду обновлять сообщение. – gooamoko

ответ

0

Я читал документацию на гибернате и нашел пример класса HibernateUtil. По сравнению с моим HibernateProvider я нашел, что похоже на мой HibernateProvider Завод был построен каждый звонок getSessionFactory(). Новая версия HibernateProvider является

package ru.gooamoko.dao; 

import org.hibernate.HibernateException; 
import org.hibernate.SessionFactory; 
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 
import org.hibernate.cfg.Configuration; 
import org.hibernate.service.ServiceRegistry; 

public class HibernateProvider { 

    private static final SessionFactory factory = buildFactory(); 

    public static SessionFactory getSessionFactory() { 
    return factory; 
    } 

    private static SessionFactory buildFactory() { 
    try { 
     Configuration configuration = new Configuration(); 
     configuration.configure(); 
     ServiceRegistry registry = new StandardServiceRegistryBuilder().applySettings(
      configuration.getProperties()).build(); 
     return configuration.buildSessionFactory(registry); 
    } catch (HibernateException ex) { 
     // Make sure you log the exception, as it might be swallowed 
     System.err.println("Initial SessionFactory creation failed." + ex); 
     throw new ExceptionInInitializerError(ex); 
    } 
    } 
} 

Итак, теперь запрос

SELECT COUNT(*) FROm pg_stat_activity; 

возвращает 6, один из которых является PSQL клиент. Даже после минуты повторной заявки. Я думаю, это прогресс.

Единственное, что остается - сделать возможной работу Hibernate с postgresql-jdbc.jat в папке Tomcat/lib и использовать jar в WEB-INF/lib. Я прочитал, что размещение postgresql-jdbc.jar в WEB-INF/lib может привести к утечкам памяти.

P.S. Я также читал, что Hibernate должен автоматически закрывать соединения при выполнении сеанса или откате, и я не должен закрывать соединения явно.

Спасибо за ваши предложения, потому что мне всегда нужен кто-то, кто держит мои глаза открытыми.