当前位置: 首页 > 知识库问答 >
问题:

Hibernate在JTA事务期间从池中获取多个JDBC连接

尉迟远
2023-03-14

我一直致力于将一个项目从BC4J迁移到JPA HiberNate。首先,我们迁移了一个范围有限的实体,并且发生了意想不到的行为。

当使用本机查询查询实体时,hibernate首先检查ehcache以查看查询是否存在,因为它不存在,它会执行查询。

DEBUG 2015-01-28 13:23:19,465 AbstractEntityManagerImpl: Looking for a JTA transaction to join
DEBUG 2015-01-28 13:23:19,465 AbstractEntityManagerImpl: No JTA transaction found
DEBUG 2015-01-28 13:23:19,466 StandardQueryCache: checking cached query results in region: org.hibernate.cache.StandardQueryCache
DEBUG 2015-01-28 13:23:19,466 EhcacheGeneralDataRegion: key: sql: select linearepro0_.C_ID as C1_215_, linearepro0_.C_ID_ACCION as C2_215_, linearepro0_.C_LINEA_OBS as C3_215_, linearepro0_.C_LINEA_REPROCESO as C4_215_ from PISOPLTA.LNA_LINEA_REPROCESO linearepro0_ where (linearepro0_.C_LINEA_OBS=? ); parameters: DEC3_CHU, ; named parameters: {}
DEBUG 2015-01-28 13:23:19,466 Cache: Cache: org.hibernate.cache.StandardQueryCache store hit for sql: select linearepro0_.C_ID as C1_215_, linearepro0_.C_ID_ACCION as C2_215_, linearepro0_.C_LINEA_OBS as C3_215_, linearepro0_.C_LINEA_REPROCESO as C4_215_ from PISOPLTA.LNA_LINEA_REPROCESO linearepro0_ where (linearepro0_.C_LINEA_OBS=? ); parameters: DEC3_CHU, ; named parameters: {}
DEBUG 2015-01-28 13:23:19,466 StandardQueryCache: Checking query spaces for up-to-dateness: [PISOPLTA.LNA_LINEA_REPROCESO]
DEBUG 2015-01-28 13:23:19,467 EhcacheGeneralDataRegion: key: PISOPLTA.LNA_LINEA_REPROCESO
DEBUG 2015-01-28 13:23:19,467 Cache: org.hibernate.cache.UpdateTimestampsCache cache - Miss
DEBUG 2015-01-28 13:23:19,467 EhcacheGeneralDataRegion: Element for key PISOPLTA.LNA_LINEA_REPROCESO is null
DEBUG 2015-01-28 13:23:19,467 StandardQueryCache: returning cached query results
DEBUG 2015-01-28 13:23:19,467 Loader: loading entity: [com.business.entity.jpa.LineaReproceso#1906]

之后,似乎 hiberate 将转到查询返回的每个实体的数据库以填充它。

DEBUG 2015-01-28 13:23:19,467 Loader: loading entity: [com.business.entity.jpa.LineaReproceso#1906]
DEBUG 2015-01-28 13:23:19,468 AbstractBatcher: about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG 2015-01-28 13:23:19,468 ConnectionManager: opening JDBC connection
DEBUG 2015-01-28 13:23:19,468 SQL: select linearepro0_.C_ID as C1_215_0_, linearepro0_.C_ID_ACCION as C2_215_0_, linearepro0_.C_LINEA_OBS as C3_215_0_, linearepro0_.C_LINEA_REPROCESO as C4_215_0_ from PISOPLTA.LNA_LINEA_REPROCESO linearepro0_ where linearepro0_.C_ID=?
DEBUG 2015-01-28 13:23:19,471 AbstractBatcher: about to open ResultSet (open ResultSets: 0, globally: 0)
DEBUG 2015-01-28 13:23:19,471 Loader: result row: EntityKey[com.business.entity.jpa.LineaReproceso#1906]
DEBUG 2015-01-28 13:23:19,471 AbstractBatcher: about to close ResultSet (open ResultSets: 1, globally: 1)
DEBUG 2015-01-28 13:23:19,471 AbstractBatcher: about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG 2015-01-28 13:23:19,471 ConnectionManager: aggressively releasing JDBC connection
DEBUG 2015-01-28 13:23:19,472 ConnectionManager: releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
DEBUG 2015-01-28 13:23:19,472 TwoPhaseLoad: resolving associations for [com.business.entity.jpa.LineaReproceso#1906]
DEBUG 2015-01-28 13:23:19,472 TwoPhaseLoad: adding entity to second-level cache: [com.business.entity.jpa.LineaReproceso#1906]
DEBUG 2015-01-28 13:23:19,473 TwoPhaseLoad: done materializing entity [com.business.entity.jpa.LineaReproceso#1906]
DEBUG 2015-01-28 13:23:19,473 StatefulPersistenceContext: initializing non-lazy collections
DEBUG 2015-01-28 13:23:19,473 Loader: done entity load
DEBUG 2015-01-28 13:23:19,474 Loader: loading entity: [com.business.entity.jpa.LineaReproceso#2659]
DEBUG 2015-01-28 13:23:19,474 AbstractBatcher: about to open PreparedStatement (open PreparedStatements: 0, globally: 0)
DEBUG 2015-01-28 13:23:19,474 ConnectionManager: opening JDBC connection
DEBUG 2015-01-28 13:23:19,474 SQL: select linearepro0_.C_ID as C1_215_0_, linearepro0_.C_ID_ACCION as C2_215_0_, linearepro0_.C_LINEA_OBS as C3_215_0_, linearepro0_.C_LINEA_REPROCESO as C4_215_0_ from PISOPLTA.LNA_LINEA_REPROCESO linearepro0_ where linearepro0_.C_ID=?
DEBUG 2015-01-28 13:23:19,477 AbstractBatcher: about to open ResultSet (open ResultSets: 0, globally: 0)
DEBUG 2015-01-28 13:23:19,477 Loader: result row: EntityKey[com.business.entity.jpa.LineaReproceso#2659]
DEBUG 2015-01-28 13:23:19,477 AbstractBatcher: about to close ResultSet (open ResultSets: 1, globally: 1)
DEBUG 2015-01-28 13:23:19,477 AbstractBatcher: about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG 2015-01-28 13:23:19,477 ConnectionManager: aggressively releasing JDBC connection
DEBUG 2015-01-28 13:23:19,477 ConnectionManager: releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]
DEBUG 2015-01-28 13:23:19,478 TwoPhaseLoad: resolving associations for [com.business.entity.jpa.LineaReproceso#2659]
DEBUG 2015-01-28 13:23:19,478 TwoPhaseLoad: adding entity to second-level cache: [com.business.entity.jpa.LineaReproceso#2659]
DEBUG 2015-01-28 13:23:19,479 TwoPhaseLoad: done materializing entity [com.business.entity.jpa.LineaReproceso#2659]
DEBUG 2015-01-28 13:23:19,479 StatefulPersistenceContext: initializing non-lazy collections
DEBUG 2015-01-28 13:23:19,479 Loader: done entity load

最糟糕的是,似乎每次打开和释放JDBC连接时。以下日志被重复接收了几次。

DEBUG 2015-01-28 13:23:19,474 ConnectionManager: opening JDBC connection
DEBUG 2015-01-28 13:23:19,474 SQL: select linearepro0_.C_ID as C1_215_0_, linearepro0_.C_ID_ACCION as C2_215_0_, linearepro0_.C_LINEA_OBS as C3_215_0_, linearepro0_.C_LINEA_REPROCESO as C4_215_0_ from PISOPLTA.LNA_LINEA_REPROCESO linearepro0_ where linearepro0_.C_ID=?
DEBUG 2015-01-28 13:23:19,477 AbstractBatcher: about to open ResultSet (open ResultSets: 0, globally: 0)
DEBUG 2015-01-28 13:23:19,477 Loader: result row: EntityKey[com.business.entity.jpa.LineaReproceso#2659]
DEBUG 2015-01-28 13:23:19,477 AbstractBatcher: about to close ResultSet (open ResultSets: 1, globally: 1)
DEBUG 2015-01-28 13:23:19,477 AbstractBatcher: about to close PreparedStatement (open PreparedStatements: 1, globally: 1)
DEBUG 2015-01-28 13:23:19,477 ConnectionManager: aggressively releasing JDBC connection
DEBUG 2015-01-28 13:23:19,477 ConnectionManager: releasing JDBC connection [ (open PreparedStatements: 0, globally: 0) (open ResultSets: 0, globally: 0)]

知道是什么导致了这种行为吗?

提前感谢。

共有1个答案

裴良弼
2023-03-14

虽然JTA规范没有强制在每个语句后释放连接,但是Hibernate这样做了,因为旧应用服务器中的一些奇怪行为导致引入了< code>AFTER_STATEMENT连接释放模式,其行为如下:

连接在每次语句执行后释放,并在运行下一条语句之前重新获取。尽管 JDBC 或 JTA 规范都不需要此策略,但此策略旨在防止应用程序服务器错误地检测到连续 EJB(Enterprise Java Beans)调用之间的连接泄漏。

因此,发生这种情况是因为您使用的是JTA环境,而不是RESOURCE_LOCAL环境。

可以通过设置以下 Hibernate 属性来覆盖此行为:

hibernate.connection.release_mode=after_transaction

您应该知道,在每个语句之后释放连接会带来性能损失,就像在< code>after_statement连接释放模式之后那样。

 类似资料:
  • 并用@Transactional注释了具体类。 我们使用Jboss应用服务器支持通过JNDI与MQ集成。这里的问题是,如果监听器中的任何层有任何异常,则整个事务不会回滚,消息也不会移动到退出队列。很明显,当我们使用Hibernate事务管理器时,它不知道其他资源,如JMS事务。 我可以安全地用JTA事务替换它吗,因为Jboss将处理整个事务管理?这样做是否有任何可预见的风险?

  • jboss narayana jta事务管理器是在我的独立java应用程序中实现的。我可以将事务管理器从jta集成到Hibernate吗?当我调用jta事务管理器的commit方法时,hibernate所做的所有更改也应该提交。请以身作则。

  • 我指的是https://developer.jboss.org/wiki/SessionsAndTransactions,目前正试图了解与JTA的划界问题。它声明在使用getCurrentSession()的特定事务中,总是给出相同的当前会话。是不是意味着: < li >如果另一个用户在另一个线程中执行同一段代码(通过查找获取一个事务,然后使用getCurrentSession()并关闭该事务),

  • 我的数据模型中有以下实体关系。 ERD Hibernate实体: 要求:我想用实体B的连接获取查询实体C,同时也急切地获取实体D。查询完成后,我希望如果我执行,它不应导致hibernate中的N 1查询问题。 我正在尝试以下JPQL查询: 这导致结果重复,因为与实体D交叉连接。我得到的不是一个结果,而是n个结果,其中n是实体D列表的大小。 我该如何避免这种情况?有没有办法在JPQL中不交叉连接地获

  • 我有一个Spring Boot应用程序,可以连接到不同的MySQL数据库。我计划将连接池支持添加到此应用程序。Tomcat JDBC连接池(默认的Spring Boot池)是否为我的每个数据库支持多个池?

  • 问题内容: 我们使用JDBC的标准代码部分是… 问题1:使用连接池时,是否应该在最后关闭连接?如果是这样,合并的目的就不会丢失吗?如果不是,那么DataSource如何知道何时释放Connection的特定实例并可以重用?我对此感到有些困惑,任何指针都表示赞赏。 问题2:以下方法是否接近标准?看起来像是尝试从池中获取连接,并且如果无法建立DataSource,请使用老式的DriverManager