java.sql.SQLException:在连接缓存中找到无效或过时的连接

时间:2014-08-31 07:03:50

标签: java hibernate connection-pooling

我正在使用带有hibernate 4的spring framework 3.2,在本地服务器(apache-tomcat v7.0)上长时间空闲时间后发送请求并且数据库位于远程服务器上时,我得到上述异常。经过几个小时的搜索,我发现问题来自连接池。我尝试了多个连接池,但没有找到令人满意的解决方案。 bellow是我的spring-data文件中的当前数据源

<bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource"
destroy-method="close">
<property name="connectionCachingEnabled" value="true" />
<property name="URL" value="${app.jdbc.url}" />
<property name="user" value="${app.jdbc.username}" />
<property name="password" value="${app.jdbc.password}" />
<property name="connectionCacheProperties">
<value>
MinLimit:70
MaxLimit:200
InitialLimit:20
ConnectionWaitTimeout:120
InactivityTimeout:180
ValidateConnection:true
</value>
</property>
</bean>

请告知。

3 个答案:

答案 0 :(得分:7)

您将获得&#34;无效或陈旧连接&#34;连接池中的连接不再主动连接到数据库时出现错误。以下是可能导致此问题的几种情况

  1. 通过dba手动中断数据库连接。例如,如果 使用&#34; ALTER SYSTEM KILL SESSION&#34;
  2. 杀死了连接
  3. 当连接池中存在连接而未用于连接时 由于强制执行超时而导致长时间断开连接 数据库(idle_time)
  4. 数据库重启
  5. 网络事件造成的 连接丢弃,可能是因为网络已成为 不可用或防火墙已经断开连接 打开太久了。
  6. 如果您要设置InactivityTimeout,则必须确保它低于数据库强制执行的IDLE_TIME。您可以使用以下查询获取IDLE_TIME

    select * from dba_profiles dp, dba_users du
    where dp.profile = du.profile and du.username ='YOUR_JDBC_USER_NAME';
    

    使用connectionCacheProperties时,请务必确保将PropertyCheckInterval属性设置为小于超时的值。默认值为900秒,这意味着缓存守护程序线程将仅每15分钟运行一次并强制执行超时。因此,您总是希望将其设置为低于超时属性的值。

    我总是确保使用0作为MinLimit。

    稍微重写一下配置文件就可以了:

    <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close">
    <property name="connectionCachingEnabled" value="true" />
    <property name="URL" value="${app.jdbc.url}" />
    <property name="user" value="${app.jdbc.username}" />
    <property name="password" value="${app.jdbc.password}" />
    <property name="connectionCacheProperties">
       <props merge="default">
        <prop key="MinLimit">0</prop>
        <prop key="MaxLimit">200</prop>
        <prop key="InitialLimit">1</prop>
        <prop key="ConnectionWaitTimeout">120</prop>
        <prop key="InactivityTimeout">180</prop>
        <prop key="ValidateConnection">true</prop>
        <prop key="PropertyCheckInterval">150</prop>
       </props>
       </property>
    </bean>
    

    您可能还会收到&#34;无效或过时的连接错误&#34;当您尝试验证从池中获取的旧连接时,您的网络实际上已断开。

答案 1 :(得分:2)

connectionCachingEnabled是关键所在。通过将其设置为true,您将使用隐式连接缓存(一种专有的Oracle连接池)来缓存连接。 但是使用ValidateConnection连接应该已经过验证。您提到过您尝试过不同的连接池。几乎所有连接池(如commons dbcpc3p0tomcat dbcp)都具有在切换到应用程序之前验证连接的功能。例如,Tomcat DBCP具有属性testOnBorrow以及validationIntervalvalidationQuery。其他游泳池也有类似的财产。对于其他游泳池,您是否也遇到了同样的问题?

答案 2 :(得分:0)

是的,我看到了错误

read:org

切换到Oracle的ucp之后,我从未见过任何过时的连接。我设置如下。

  java.sql.SQLException: Invalid or Stale Connection found in the Connection Cache.