在我的应用程序中,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),以便它不会无限期地阻塞。