在我的应用程序中,Spring 管理用于数据库访问的连接池。 Hibernate 使用这些连接进行查询。乍一看,我对池没有任何问题:它可以在并发客户端和只有一个连接的池中正常工作。我可以执行很多查询,所以我认为我(或 Spring)不会留下打开的连接。
我的问题在一段时间不活动后出现(有时 30 分钟,有时超过 2 小时)。然后,当 Hibernate 进行一些搜索时,它会持续太多。将 log4j 级别设置为 TRACE,我得到以下日志:
...
18:27:01 DEBUG nsactionSynchronizationManager - Retrieved value [org.springframework.orm.hibernate3.SessionHolder@99abd7] for key [org.hibernate.impl.SessionFactoryImpl@7d2897] bound to thread [http-8080-Processor24]
18:27:01 DEBUG HibernateTransactionManager - Found thread-bound Session [org.hibernate.impl.SessionImpl@8878cd] for Hibernate transaction
18:27:01 DEBUG HibernateTransactionManager - Using transaction object [org.springframework.orm.hibernate3.HibernateTransactionManager$HibernateTransactionObject@1b2ffee]
18:27:01 DEBUG HibernateTransactionManager - Creating new transaction with name [com.acjoventut.service.GenericManager.findByExample]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
18:27:01 DEBUG HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@8878cd]
18:27:01 TRACE SessionImpl - setting flush mode to: AUTO
18:27:01 DEBUG JDBCTransaction - begin
18:27:01 DEBUG ConnectionManager - opening JDBC connection
在这里它会卡住大约 2 - 10 分钟。但随后继续:
18:30:11 DEBUG JDBCTransaction - current autocommit status: true
18:30:11 DEBUG JDBCTransaction - disabling autocommit
18:30:11 TRACE JDBCContext - after transaction begin
18:30:11 DEBUG HibernateTransactionManager - Exposing Hibernate transaction as JDBC transaction [jdbc:oracle:thin:@212.31.39.50:30998:orcl, UserName=DEVELOP, Oracle JDBC driver]
18:30:11 DEBUG nsactionSynchronizationManager - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@843a9d] for key [org.apache.commons.dbcp.BasicDataSource@7745fd] to thread [http-8080-Processor24]
18:30:11 DEBUG nsactionSynchronizationManager - Initializing transaction synchronization
...
在那之后,它可以正常工作,直到另一段不活动时间。恕我直言,连接池似乎返回了一个无效/关闭的连接,当 Hibernate 意识到这一点时,向池中请求另一个连接。
我不知道如何解决这个问题或我可以做些什么来界定它。任何帮助实现这一目标的人都将不胜感激。
谢谢。
编辑:好吧,它终于归功于防火墙规则。数据库检测到连接丢失,但池(dbcp 或 c3p0)没有。因此,它尝试查询数据库但没有成功。对我来说仍然奇怪的是超时期限变化很大。也许规则特别奇怪或者防火墙没有正常工作。反正我没法接触那台机器,只能等着解释。 :(
最佳答案
我以前遇到过这样的问题,当时数据库位于一个单独的盒子上,中间有一个防火墙设置为空闲连接超时。
在某些情况下,防火墙以 JDBC 端未检测到的方式切断连接,并且尝试使用它会导致无限期阻止。
在我的例子中,它是一个自定义连接池,它在从池中返回之前向连接发送测试查询。我将此测试查询配置为超时(使用 Statement.setQueryTimeout),这样它就不会无限期地阻塞。
关于java - 连接在不活动时间后挂起,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1888923/