Hibernate不释放数据库连接

时间:2010-03-19 12:35:28

标签: hibernate connection-pooling oracle9i

以下是配置详情:

<property name="hibernateProperties">
   <props>
    <prop key="hibernate.dialect">
     org.hibernate.dialect.Oracle9iDialect
    </prop>
    <prop key="hibernate.show_sql">false</prop>
    <prop key="hibernate.cache.provider_class">
     org.hibernate.cache.OSCacheProvider
    </prop>
    <prop key="hibernate.cache.use_second_level_cache">
     true
    </prop>
    <!-- <prop key="hibernate.hbm2ddl.auto">update</prop>-->
    <!-- HIBERNATE CONNECTION POOLING!!-->
    <prop key="c3p0.acquire_increment">5</prop>
    <prop key="c3p0.idle_test_period">100</prop>
    <!-- seconds -->    
    <prop key="c3p0.max_statements">5</prop>
    <prop key="c3p0.min_size">15</prop>
                            <prop key="c3p0.max_size">100</prop> 
    <prop key="c3p0.timeout">100</prop>
    <!-- seconds -->
   </props>
  </property>

我们的应用程序是通过Spring&amp; amp;冬眠。

一旦我们将应用程序启动并点击它,它就会打开140个连接并且不会释放它。

我们的DAO看起来像这样:

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
...
public class ActionDAO extends HibernateDaoSupport implements IActionDAO {
 public Action findById(ActionPK actionPK) {
  return (Action) getHibernateTemplate().get(Action.class, actionPK);
 }

 public void add(Action action) {
  getHibernateTemplate().save(action);
 }
}

6 个答案:

答案 0 :(得分:2)

前段时间我们遇到过类似的问题,根本原因是Hibernate会话工厂在应用程序终止之前没有关闭。虽然我知道你正在使用Spring,它应该自动处理它,但它仍然值得检查。

答案 1 :(得分:1)

您的会话是否属于交易?如果是,则会话/连接关闭可能仅在事务结束时发生,如果没有发生,则会发生泄露的连接。

在org.hibernate.jdbc和org.hibernate.transaction上启用调试日志记录可能会有所帮助...也可以查看HibernateTemplate类(HibernateDaoSupport使用)并查看如何配置会话创建/关闭的选项。您可能只想将DAO对象包装在Spring事务包装器或类似的东西中。

答案 2 :(得分:1)

我不认为你的c3p0设置被击中了,因为你看到了&gt; 100分贝连接。话虽这么说,你应该将idle_test_period设置为小于c3p0超时的值。

此外,哪个版本的hibernate在确定为什么没有使用c3p0时很重要。

你也提到了春天;你需要看看你在交易方面做了些什么。您是否有某种服务或某种情况,或者在您的情况下,是否未将DAO用于交易?

答案 3 :(得分:0)

如果你正在使用spring autowiring和hibernateTemplate

请确保您没有创建多个HibernateTemplate实例,即

ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("META-INF/spring/applicationContext.xml");
Object o=context.getBean("hibernateTemplate");

对象o必须在某处缓存,并在您的应用代码要求hibernatetemplate的情况下返回。

由于

答案 4 :(得分:0)

删除最小尺寸并尝试:c3p0.min_size

答案 5 :(得分:0)

我在Jboss-hibernate中遇到了类似的问题。我们的印象是,在事务会话下执行读取操作时,无需提交事务。但是,我们意识到交易必须,但它只是读取操作(如果您已经开始交易)。一旦我们将交易交给各地,泄漏就不复存在了。

Buggy代码是这样的:

  1. 开始交易
  2. 执行读取操作
  3. 关闭会话
  4. 以上程序取代了以上程序,泄漏消失了。

    1. 开始交易
    2. 执行读取操作
    3. 提交交易
    4. 关闭会话