代码之家  ›  专栏  ›  技术社区  ›  sinuhepop

连接在非活动时间后挂起

  •  8
  • sinuhepop  · 技术社区  · 16 年前

    在我的应用程序中,Spring为数据库访问管理连接池。Hibernate使用这些连接进行查询。乍一看,我对池没有任何问题:它在并发客户机和只有一个连接的池中正常工作。我可以执行很多查询,所以我(或Spring)不会留下打开的连接。

    我的问题出现在一段时间不活动之后(有时30分钟,有时超过2小时)。然后,当冬眠进行一些搜索时,它会持续太久。将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
    ...
    

    在那之后,它可以毫无问题地工作,直到另一个不活动的时期。imho,连接池似乎返回一个无效/关闭的连接,当Hibernate意识到这一点时,请求另一个到池的连接。

    我不知道该如何解决这个问题,也不知道我可以做些什么来界定它。任何帮助实现这一目标的人都将不胜感激。

    谢谢。

    编辑:好吧,最后是因为防火墙规则。数据库检测到连接丢失,但池(dbcp或c3p0)没有。因此,它试图查询数据库,但没有成功。对我来说仍然奇怪的是超时时间是非常可变的。也许规则特别奇怪,或者防火墙不能正常工作。不管怎样,我无法使用那台机器,只能等待解释。:。(

    5 回复  |  直到 12 年前
        1
  •  7
  •   Joe    16 年前

    我以前遇到过这样的问题,当数据库在一个单独的盒子上,并且在中间有一个防火墙,设置为超时空闲连接。

    在某些情况下,防火墙以JDBC端检测不到的方式切断连接,并且试图使用它会导致不确定的块。

    在我的例子中,它是一个自定义连接池,在从池返回连接之前,它向连接发送了一个测试查询。我将此测试查询配置为具有超时(使用statement.setquerytimeout),以便它不会无限期阻塞。

        2
  •  1
  •   Aaron Digulla    16 年前

    检查池实现的配置。通常,它是 Apache DBCP 哪个有 a timeout 每次连接后,它都会关闭。

    在你的代码中,你不应该保持联系。拿一个,用一下,马上关上。游泳池会确保这个不会花费太多。

        3
  •  1
  •   Jayadp    16 年前

    解决空闲超时问题的一种方法是使用双连接池,一个处于活动状态,另一个处于备用状态(尚未创建任何连接)。使用触发时间远小于防火墙空闲超时的计时器,并在连接池之间切换。我试过这个,它起作用了。

        4
  •  1
  •   MIJAEL    15 年前

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

    更重要的是添加testonborrow和validationquery

        5
  •  1
  •   kman    12 年前

    我们解决了类似症状的问题,这些症状也被证明是由防火墙引起的。

    我们可以通过更改TestWhileIdle连接池属性来解决这个问题,该属性可以防止连接闲置和防火墙关闭连接。参见 Apache commons dbcp BasicDataSource . 下面是配置文件persistentce-context.xml中的一个应用程序,它修复了问题:

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

    很可能我们只需要添加testwileidle(默认情况下为false),但为了更好的度量,添加了其他两个属性。

    在我们的例子中,这里是我们看到的一些日志。注意,在这个调试日志中,需要16分钟才能打开连接,然后才能使用连接,这就是导致所有内容挂起的原因。没有错误,很难找到。

    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