【问题标题】:Seems like Hibernate exceeds connection limit好像休眠超过了连接限制
【发布时间】:2014-08-27 08:22:22
【问题描述】:

谁能帮我解决这个问题? 我有一个 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, com.mchange.v2.resourcepool.BasicResourcePool@4df5a3a4 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.mchange.v2.resourcepool.BasicResourcePool$ScatteredAcquireTask@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)

我应该如何以及在哪里更正关闭打开的连接?

感谢您为我浪费时间。

【问题讨论】:

  • 可能是因为您没有关闭与数据库的连接?您应该以任何方式使用连接池。
  • 请不要链接到代码。直接在您的问题中包含最相关的部分。如果您将来删除该 github 项目或页面内容发生更改,则该链接将不会对其他读者有所帮助。
  • @BackSlash 好的。我会更新帖子。
  • @Andremoniy 你能给我一个简单的例子,我在哪里以及如何关闭连接?我在哪里可以阅读有关使用连接池的信息?
  • 请发布完整的异常堆栈跟踪。 “无法打开连接”是结果,而不是实际问题。另请注意,这可能与数据库服务器的配置方式完全相关。

标签: java hibernate tomcat


【解决方案1】:

我已经阅读了 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 可能会导致内存泄漏。

附:我还读到,当会话提交或回滚时,Hibernate 应该自动关闭连接,我不需要显式关闭连接。

感谢您的建议,因为我总是需要一个让我睁大眼睛的人。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-31
    • 2012-05-28
    • 2012-01-06
    • 2011-09-26
    • 2016-09-24
    • 2017-08-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多