Hibernate 不释放数据库连接

发布于 08-26 00:14 字数 1533 浏览 13 评论 0原文

以下是配置细节:

<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 & 开发的。冬眠。

一旦我们启动应用程序并点击它,它就会打开 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);
 }
}

Following is the configuration details:

<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>

Our application is developed through Spring & Hibernate.

Once we bring the application up and hit it, its opening 140 connections and not releasing it.

Our DAO looks like this:

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);
 }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

江南烟雨〆相思醉2024-09-02 00:14:27

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

We had a similar issue some time ago, and the root cause was that the Hibernate session factory was not closed before the app terminated. Although I understand that you are using Spring, which is supposed to take care of this automagically, still it might be worth checking.

携余温的黄昏2024-09-02 00:14:27

您的会话是交易的一部分吗?如果是,那么会话/连接关闭可能仅在事务结束时发生,如果没有发生,您将获得泄漏的连接。

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

Are your sessions part of a transaction? If they are, then the session/connection closing may only happen when the transaction ends, and if that's not happening, you'll get leaked connections.

Enabling debug logging on org.hibernate.jdbc and org.hibernate.transaction may help... also look at the HibernateTemplate class (which HibernateDaoSupport uses) and see the options for how session creation/closing is configured. You may just want to wrap your DAO objects inside a Spring transaction wrapper or something similar.

巡山小妖精2024-09-02 00:14:27

我认为你的 c3p0 设置没有受到影响,因为你有 > 100 个数据库连接。也就是说,您应该将idle_test_period 设置为小于c3p0 超时的值。

此外,哪个版本的 hibernate 对于确定为什么不使用 c3p0 很重要。

你还提到了春天;您需要查看您在交易方面所做的事情。您是否有某种服务或某些东西,或者在您的情况下,没有将您的 DAO 使用包装在事务中?

I don't think your c3p0 settings are being hit, seeing as you have > 100 db connections. That being said you should set your idle_test_period to a value less than c3p0 timeout.

In addition, which version of hibernate matters in determining why c3p0 is not being used.

You also mentioned spring; you need to see what you're doing with regard to transactions. Do you have some sort of service or something that is or in your case, is not wrapping your DAO use in a transaction?

贪了杯2024-09-02 00:14:27

如果您正在使用 spring 自动装配和 hibernateTemplate,

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

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

对象 o 必须缓存在某处,并在您的应用程序代码请求实例时返回休眠模板。

谢谢

If u are using spring autowiring and hibernateTemplate

please make sure that you are not creating more than one instance of HibernateTemplate, ie

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

The object o has to be cached somewhere and returned when your app code is asking for instance of hibernatetemplate.

Thanks

止于盛夏2024-09-02 00:14:27

删除最小大小并尝试:c3p0.min_size

Delete the min size and try: c3p0.min_size

看透却不说透2024-09-02 00:14:27

我在 Jboss-hibernate 中遇到了类似的问题。我们的印象是,在事务会话下执行读取操作时,无需提交事务。然而,我们意识到事务必须提交,尽管它只是一个读取操作(如果您已经开始事务)。一旦我们在各处提交了交易,泄漏就消失了。

有错误的代码是这样的:

  1. 开始事务
  2. 执行读操作
  3. 关闭会话

上面被替换为以下过程,泄漏消失了。

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

I had a similar issue in Jboss-hibernate. We had the impression that while performing a read operation under a transactional session, there was no need to commit the transaction. However we realized that the transaction must be commited although it is only a read opeartion (if you have begun a transaction). Once we commited the transaction everywhere, the leakage was gone.

Buggy code was like this:

  1. Begin transaction
  2. Execute read operation
  3. Close the session

The above was replaced with the following procedure and the leakage was gone.

  1. Begining transaction
  2. Perform read operation
  3. Commit the transaction
  4. Close the session
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文