【问题标题】:c3p0 not releasing connection when max_size reached达到 max_size 时 c3p0 不释放连接
【发布时间】:2015-03-17 17:39:52
【问题描述】:

我正在尝试以一种方法对数据库执行 10 次获取。 我正在使用带有 c3p0 0.9.5 的 Hibernate 3.5.x 和 Spring 3.2.13。

我的 hibernate.cfg.xml 包含以下内容:

<property name="hibernate.c3p0.acquire_increment">1</property>
<property name="hibernate.c3p0.idle_test_period">300</property>
<property name="hibernate.c3p0.max_size">10</property>
<property name="hibernate.c3p0.max_statements">0</property>
<property name="hibernate.c3p0.min_size">10</property>
<property name="hibernate.c3p0.timeout">600</property>

在 c3p0 的调试中这一切都很好:

[managed: 10, unused: 0, excluded: 0] 
[managed: 10, unused: 1, excluded: 0] 
[managed: 10, unused: 2, excluded: 0] 
[managed: 10, unused: 3, excluded: 0] 
[managed: 10, unused: 4, excluded: 0] 
[managed: 10, unused: 5, excluded: 0] 
[managed: 10, unused: 6, excluded: 0] 
[managed: 10, unused: 7, excluded: 0] 
[managed: 10, unused: 8, excluded: 0] 
[managed: 10, unused: 9, excluded: 0]

这一切都发生得非常快(不到 0.5 秒)

但如果我添加一个额外的 get 即 11,那么我会得到以下结果:

[managed: 10, unused: 0, excluded: 0] repeatedly

在连接超时之前它不会改变。

我正在像这样使用 Springs 事务管理器:

<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory" />
</bean>

<tx:annotation-driven transaction-manager="transactionManager" />

并使用以下基本上调用 findOne()

public abstract class AbstractDAO<T extends Serializable> {
    private Class< T > clazz;

    @Autowired
    private SessionFactory sessionFactory;

    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public void setClazz(final Class<T> clazzToSet) {
        clazz = clazzToSet;
    }

    @Transactional
    public T findOne(final long id) {
        return (T) getCurrentSession().get(clazz, id);
    }

...
}

请告诉我哪些其他信息可能有助于诊断。

我可能做错了什么?

【问题讨论】:

  • 你有没有做connection.close()来释放它?
  • 我已经用事务管理器信息更新了我的问题。这段代码还需要关闭吗?

标签: java spring hibernate c3p0


【解决方案1】:

您正在泄漏连接。

您没有关闭()您的连接。 (请在 finally 块中健壮地关闭()它们,以便保证对 close() 的调用 - 即不能被 finally 中的先前异常跳过 - 或者如果 Java 7+ 使用 try-with-resources 则更好。

注意:在 Hibernate 中,包装连接的是 Session,您必须确保获得 close()ed。

【讨论】:

  • 我已经用事务管理器信息更新了我的问题。这段代码还需要关闭吗?此外,在使用 10 次的测试中,日志显示它正在关闭。为什么要添加第11个停止关闭连接?
【解决方案2】:

所以看起来你不能在同一个线程中使用超过 hibernate.c3p0.max_size 的连接,即如果 hibernate.c3p0.max_size 设置为 10,那么你不能在同一个线程中有 11 个连接。我猜c3p0只有在线程完成后才会释放连接。

我测试这个的方法是在方法中有 10 次获取,然后休眠 15 秒。我执行了两次该方法,第一个方法使用 10 个连接运行。 15 秒后,该方法完成,第二次执行成功运行,使用了另外 10 个连接,然后在 15 秒后释放。

我想我能理解为什么会这样。我想我将不得不重构/重新设计我对连接的使用......

更新: 我找到了我设置为 after_statement 的 hibernate.connection.release_mode 属性。这似乎在执行后释放了连接。请参阅here 了解更多信息

【讨论】:

    猜你喜欢
    • 2012-04-22
    • 2017-06-06
    • 1970-01-01
    • 2013-05-19
    • 2016-10-24
    • 2013-01-29
    • 2015-11-20
    • 2010-11-25
    • 2017-06-21
    相关资源
    最近更新 更多