【问题标题】:Hibernate session.close() not returning connection to poolHibernate session.close()不返回连接池
【发布时间】:2011-04-24 20:33:31
【问题描述】:

我的应用程序有长时间运行的事务,因此我在每个方法的末尾尝试了选项 session.close() 以确保连接对象不会无限期地保持很长时间。

当使用 session.close() 选项时,我可以看到 Hibernate 的 session 对象和从 session.connection() 获得的相应 Connection 对象被正确销毁。但问题在于连接池。会话获得的连接即使关闭会话后也不会释放回连接池。发现其他请求正在等待来自池的连接。

我在我的应用程序中使用 JTA 事务。在 hibernate.cfg.xml 中,我将 connection.release_mode 设置为 auto(默认)并将 connection.autocommit 设置为 true。

有人遇到过这个问题吗?请让我知道我在这里缺少什么。

跟进:这是我的hibernate配置文件详情:

<property name="connection.datasource">MXoraDS</property> 
<property name="dialect">org.hibernate.dialect.Oracle9Dialect</property> 
<property name="connection.release_mode">after_statement</property> 
<property name="hibernate.transaction.manager_lookup_class">org.hibernate.transaction.WeblogicTransactionManagerLookup</property> 
<property name="hibernate.transaction.factory_class">org.hibernate.transaction.JTATransactionFactory</property>
<property name="hibernate.current_session_context_class">org.hibernate.context.JTASessionContext</property> 
<property name="transaction.auto_close_session">true</property> 
<property name="max_fetch_depth">2</property>

我们在连接到 Oracle DB 的应用层使用 JSF 和 EJB 2.1。 after_statement 似乎没有释放与池的连接。如果您需要更多详细信息,请告诉我。

【问题讨论】:

  • 您应该提供有关您的配置的更多信息。比如哪个事务管理器和事务配置,你如何管理你的事务等等

标签: hibernate session ejb jta


【解决方案1】:

我在我的应用程序中使用 JTA 事务。在 hibernate.cfg.xml 中,我已将 connection.release_mode 设置为 auto(默认)并将 connection.autocommit 设置为 true。

您能否尝试将hibernate.connection.release_mode 属性明确定义为after_statement?我知道这应该是默认设置,但根据您的上下文(您可以使用 Spring 吗?),auto 可能不会按预期运行(请参阅here here)。

作为参考,下面是Table 3.4. Hibernate JDBC and Connection Properties 写的关于属性hibernate.connection.release_mode 的内容:

指定何时应该休眠 释放 JDBC 连接。默认, JDBC 连接一直保持到 会话显式关闭或 断开连接。 对于应用程序 服务器 JTA 数据源,使用 after_statement 积极进取 每次 JDBC 后释放连接 调用。 对于非 JTA 连接,它 通常是有意义的释放 在每个末尾的连接 交易,通过使用 after_transactionauto会 为 JTA 选择 after_statement 和 CMT 交易策略和 after_transaction 用于 JDBC 交易策略。

例如 auto(默认)| on_close | after_transaction | after_statement

此设置仅影响会话 从返回 SessionFactory.openSession。为了 通过获得的会话 SessionFactory.getCurrentSessionCurrentSessionContext 执行 配置为使用控制 那些的连接释放模式 会议。见Section 2.5, “Contextual sessions”

如果没有帮助,请添加有关您的环境和配置(Spring?)、如何获取会话等的更多详细信息。

【讨论】:

  • 这是我的休眠配置文件详细信息:MXoraDSorg.hibernate.dialect.Oracle9Dialectafter_statementorg.hibernate.transaction.WeblogicTransactionManagerLookup org.hibernate.transaction.JTATransactionFactory
  • 更多细节:org.hibernate.context.JTASessionContexttrue2 我们在连接Oracle DB的应用层使用JSF和EJB 2.1。 after_statement 似乎没有释放与池的连接。如果您需要更多详细信息,请告诉我。
【解决方案2】:

如果您使用的是 JDBCTransactionManager,则事务结束时连接将返回到连接池。

【讨论】:

  • 您好,感谢您的回复。我们正在使用 Weblogic 事务管理器(org.hibernate.transaction.WeblogicTransactionManagerLookup)和 JTATransactionFactory。事务由处理连接对象的容器管理。使用 CMT 时,是否无法通过关闭休眠会话以编程方式将连接返回到连接池?
  • 在这种情况下,weblogic 将连接添加到事务。当事务结束时,weblogic 会将连接返回到池中
  • 是的,它在事务通过提交或回滚结束后返回到池的连接。但是在事务中,我调用了需要较长时间执行的外部应用程序。我正在尝试在调用长时间运行的方法之前关闭连接并将其返回到池中,并在需要时再次重新连接。这样我就不会长时间保持连接。请告诉我这是否可能。我可以使用 session.close 返回到池的连接还是在长时间运行的事务中断开连接?
  • 您无法在事务进行时将连接返回到池中。暂停交易没有任何效果。所以重构你的程序,以便在事务之外执行长时间运行的调用,即在你开始事务之前。或向您的连接池添加更多连接
猜你喜欢
  • 1970-01-01
  • 2023-03-24
  • 2021-02-14
  • 2023-04-07
  • 1970-01-01
  • 2015-12-04
  • 1970-01-01
  • 2015-03-28
  • 1970-01-01
相关资源
最近更新 更多