Mar*_*her 5 java hibernate transactions jta wildfly
在分析Wildfly 10.1在高压情况下的一些性能问题时,我得出结论,有时并行HTTP线程会相互阻塞.
原因似乎是在某些HTTP请求中我们执行了两个JPQL查询(实际上是一个删除和一个选择),有时两个中的第二个根本没有从池中获得JDBC连接.(我们使用IBM DB2,如果这很重要......)由于第一个语句已经建立连接,这似乎相当荒谬.
在阅读了Hibernate文档之后,我看到默认为hibernate.connection.release_modeis after_statement,after_transaction不建议用于JTA应用程序...
那么......我现在有几个问题:
after_statement有意义?(除非你当然有auto_comit ......)after_transaction在JTA应用程序中使用?after_transaction应该解决所描述的问题?任何帮助表示赞赏!
六年过去了,但我希望这可以帮助未来的读者。
\n几年来,我们遇到了一个生产错误,该错误不断耗尽 Atomikos 管理的 Hibernate (3.xx) 和 JTA 集成中的池连接。
\n通过我们的 Atomikos“恢复策略”(即强制释放所有连接),这一切都很好,直到最近与在 K8S 中拥有多个实例的直接现代合作者的升级推动了应用程序的临界点,我们需要解决这个问题。
\n四处浏览,我发现了以下一组:
\nsetProperty("hibernate.connection.release_mode", "after_transaction");\nRun Code Online (Sandbox Code Playgroud)\n经过研究后,我想到了这个问题(以及有关此模式的其他多个不清楚/未解答的问题)
\n以下是调查结果:
\n2005 年,Hibernate JTA 集成似乎引起了问题,因此提出了HHH-1287 :
\n\n\n看起来 ExtendedJTATransaction 在 CMT 完成后根本不可用,并且 WebSphereExtendedJTATransactionLookup 类尝试在 java:comp/websphere/ExtendedJTATransaction 中查找它,作为正常“完成后”回调的一部分。
\n当 afterCompletion 回调事件触发并且从 ConnectionManager.afterTransaction() 调用 ConnectionManager.isAggressiveRelease() 方法时,会出现此问题。这会尝试检查事务是否正在进行中。该测试实际上会导致创建事务管理器(以及对当前事务的查找)。ExtendJTATransaction 的查找失败并引发异常(请参阅下面的堆栈跟踪)。
\n尽管SSB和MDB的操作方式可能存在不一致,但公平地说,如果事务已完成,则可能不可用。因此需要一种解决方法。
\n
因此,在连接管理器中进行了更改以规避此场景中的 JTA 事务检查:(随后进行了进一步改进)
\nprivate boolean isAggressiveReleaseNoTransactionCheck() {\n if (releaseMode == ConnectionReleaseMode.AFTER_STATEMENT) {\n return true;\n }\n else {\n boolean inAutoCommitState;\n try {\n inAutoCommitState = isAutoCommit();\n }\n catch( SQLException e ) {\n inAutoCommitState=true; // assume we are in an auto-commit state\n }\n return releaseMode == ConnectionReleaseMode.AFTER_TRANSACTION && inAutoCommitState;\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n验证此方法有效后,它随 3.xx 的以下文档一起发布:
\n表\xc2\xa03.4.\xc2\xa0Hibernate JDBC 和连接属性
\n| 物业名称 | 目的 |
|---|---|
| hibernate.connection.release_mode | 指定 Hibernate 何时应释放 JDBC 连接。默认情况下,JDBC 连接将一直保持到显式关闭或断开会话为止。对于应用程序服务器 JTA 数据源,您应该使用\xc2\xa0 after_statement\xc2\xa0 在每次 JDBC 调用后主动释放连接。对于非 JTA 连接,通常可以使用 \xc2\xa0 在每个事务结束时释放连接。after_transaction\xc2\xa0 \xc2\xa0 将为JTA 和 CMTauto选择 \xc2\xa0 \xc2\xa0after_statement事务策略和\xc2\xa0 after_transaction\xc2\xa0 为 JDBC 事务策略。例如。\xc2\xa0 auto\xc2\xa0(默认) /\xc2\xa0 on_close\xc2\xa0/\xc2\xa0 after_transaction\xc2\xa0/after_statement |
\n\n对于应用程序服务器 JTA 数据源,您应该使用\xc2\xa0
\nafter_statement\xc2\xa0 在每次 JDBC 调用后主动释放连接。
因此,这是围绕实现“资源遏制”检查的某些容器(不仅仅是 EE 容器)进行的工作。
\nHibernate 会话推迟获取 JDBC 连接,直到它真正需要一个连接为止,这可能会导致如下情况,即 2 个 Bean 共享一个会话/EM:
\n此时,这些容器将其视为“泄漏”连接,因为在获取句柄的范围结束时尚未释放该句柄。因此,积极释放。
\n您可以在这里详细阅读有关此内容的更多信息:[hibernate-dev] - 连接释放模式
\n小智 0
连接池管理的问题可能发生在多个级别:数据库、hibernate、应用程序服务器。为了方便这种管理,强烈建议使用C3p0,它是一个Java库,它提供了管理数据库连接的便捷方法。请参阅文档C3Po 链接
然后,您可以在 hibernate.cfg.xml 文件中配置 JTA 事务的发布模式。最好将其保留为默认值:“auto”,如下所示:
<property name="hibernate.connection.release_mode">auto</property><!-- Release mode database connection- auto the default value -->
<property name="hibernate.c3p0.max_statements">0</property> <!-- Number of prepared statements will be cached. 0 no caching -->
<property name="hibernate.c3p0.max_size">1000</property> <!-- Max connection pool size -->
<property name="hibernate.c3p0.min_size">50</property> <!-- Min connection pool size -->
<property name="hibernate.c3p0.timeout">550</property> <!-- Time in seconds before free a connection. 0 no expiration -->
<property name="hibernate.c3p0.idleConnectionTestPeriod">1800</property> <!-- idle time in seconds before testing if a connection is valid - Setting a fairly long idleConnectionTestPeriod, and not testing on checkout and check-in at all is an excellent, high-performance approach. -->
<property name="hibernate.c3p0.preferredTestQuery">SELECT 1;</property>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
2311 次 |
| 最近记录: |