Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 连接在非活动时间后挂起_Java_Oracle_Hibernate_Spring_Jdbc - Fatal编程技术网

Java 连接在非活动时间后挂起

Java 连接在非活动时间后挂起,java,oracle,hibernate,spring,jdbc,Java,Oracle,Hibernate,Spring,Jdbc,在我的应用程序中,Spring管理数据库访问的连接池。Hibernate使用这些连接进行查询。乍一看,我对池没有任何问题:它可以正确地处理并发客户端和只有一个连接的池。我可以执行很多查询,所以我认为我(或Spring)不会留下打开的连接 我的问题出现在一段时间的不活动之后(有时30分钟,有时超过2小时)。然后,当Hibernate进行一些搜索时,它会持续太久。将log4j级别设置为TRACE,我得到以下日志: ... 18:27:01 DEBUG nsactionSynchronizationM

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

解决空闲超时问题的一种方法是使用两个连接池,一个是活动的,另一个是备用的(尚未创建任何连接)。有一个触发时间远小于防火墙\u空闲\u超时的计时器,并在连接池之间切换。我尝试了这个方法,并且它可以正常工作。

您必须在数据源中添加一些参数:


更重要的是,添加TestOnBrook和validationQuery,我们解决了类似症状的问题,这些症状也被证明是由防火墙引起的

我们可以通过更改testWhileIdle连接池属性(防止连接空闲)和防火墙关闭连接来解决此问题。请参阅。以下是配置文件persistentce-context.xml中修复此问题的示例:

<property name="testWhileIdle">
  <value>true</value>
</property>
<property name="minEvictableIdleTimeMillis">
  <value>600000</value>
</property>
<property name="timeBetweenEvictionRunsMillis">
  <value>600000</value>
</property>

Spring管理我的连接,因此我不是必须明确调用Connection.close()的人。是吗?正如您所说,我使用的是org.apache.commons.dbcp.BasicDataSource,带有destroy method=“close”。我将对此进行研究。还有两个问题来源:您和数据库服务器之间可能存在防火墙(但空闲TCP连接上的2h超时有点短)。或者您的数据库配置为在一段时间后关闭空闲连接。请参阅DBCP的其他配置选项,以检查是否存在死连接,并定期ping数据库以保持管道打开。至于关闭:否,您不应关闭它,但应结束事务(这将使Spring看到连接可以返回到池)。我不知道为什么您会使用自定义池只发送测试查询。一个简单的连接池和/或容器管理的数据源已经能够做到这一点。例如DBCP和Tomcat JNDI也是如此。请在每个关键字下使用配置文档
validationQuery
。这是在一个项目中(很久以前)这使用了一个定制的连接池,并且在代码部分中确实做了与DBCP中的validationQuery类似的事情。你是对的。问题似乎是一些防火墙规则超出了我的控制。我认为最好的解决方案是改变防火墙行为。谢谢。你如何确定这是否是防火墙问题?我面临一个新的问题类似的问题是dbcp无限期地挂起在我的Spring批处理事务上,并且永远不会返回
09-06-13 @ 16:36:34 [DEBUG] HibernateTransactionManager - Preparing JDBC Connection of Hibernate Session [org.hibernate.impl.SessionImpl@db17ab]
09-06-13 @ 16:36:34 [DEBUG] ConnectionManager - opening JDBC connection
09-06-13 @ 16:52:00 [DEBUG] DataSourceUtils - Setting JDBC Connection
09-06-13 @ 16:52:00 [DEBUG] JDBCTransaction - begin
09-06-13 @ 16:52:00 [DEBUG] JDBCTransaction - current autocommit status: true