似乎休眠超过连接限制
问题描述:
任何人都可以帮我解决这种情况吗? 我有一个Tomcat和简单的JSF应用程序:https://github.com/gooamoko/jsfbilling/。 当我在Tomcat上运行应用程序时,它运行正常,但是在几次请求(例如10个快速刷新页面)之后,引发异常can't open connection
。 我认为这很正常,但错误在哪里?似乎休眠超过连接限制
在配置文件中的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类新
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();
}
}
在Tomcat登录我看到这个
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)
如何以及在哪里应该我纠正关闭打开的连接?
感谢您为我浪费时间。
答
我读过Hibernate文档,并找到类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能够在Tomcat/lib文件夹中使用postgresql-jdbc.jat,而在WEB-INF/lib中不使用jar。我读过将postgresql-jdbc.jar放入WEB-INF/lib中可能导致内存泄漏。
P.S.我还读到,当会话提交或回滚时,Hibernate应该自动关闭连接,而且我不需要明确关闭连接。
感谢您的建议,因为我总是需要一个让我睁大眼睛的人。
可能是因为您没有关闭与数据库的连接?任何你应该使用连接池的方式。 – Andremoniy 2014-08-27 08:23:55
请不要链接到代码。直接在你的问题中包含最相关的部分。如果您将删除该github项目或将来更改页面内容,则该链接对其他读者不会有所帮助。 – BackSlash 2014-08-27 08:25:15
@BackSlash好的。我会更新帖子。 – gooamoko 2014-08-27 08:29:30