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

java.sql.SQLException:在连接缓存中找到无效或过时的连接,java,hibernate,connection-pooling,Java,Hibernate,Connection Pooling,我使用的是SpringFramework3.2和Hibernate4,在本地服务器(ApacheTomcatV7.0)上长时间空闲并且数据库位于远程服务器上之后发送请求时出现上述异常。经过数小时的搜索,我发现问题来自连接池。我尝试了大量的连接池,但没有找到令人满意的解决方案。下面是我的spring数据文件上的当前数据源 <bean id="dataSource" class="oracle.jdbc.pool.OracleDataSource" destroy-method="close"

我使用的是SpringFramework3.2和Hibernate4,在本地服务器(ApacheTomcatV7.0)上长时间空闲并且数据库位于远程服务器上之后发送请求时出现上述异常。经过数小时的搜索,我发现问题来自连接池。我尝试了大量的连接池,但没有找到令人满意的解决方案。下面是我的spring数据文件上的当前数据源

<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>

最低限额:70
最高限额:200
初始限制:20
ConnectionWaitTimeout:120
不活动时间:180
ValidateConnection:true

请告知。

此处的关键是连接计算机化。通过将其设置为true,您将使用隐式连接缓存(一种专有的Oracle连接池)来缓存连接。
但是使用
ValidateConnection
时,应该已经验证了连接。您提到您尝试了不同的连接池。几乎所有连接池,如(,)都有这样的功能,可以在将连接移交给应用程序之前验证连接。例如,has property
testOnBorrow
以及
validationInterval
validationQuery
。其他池也有类似的属性。对于其他池,您是否也遇到了同样的问题?

当连接池中的连接不再主动连接到数据库时,您将收到“无效或过时连接”错误。下面是一些可能导致这种情况的场景

  • dba从数据库手动中止连接。例如,如果 已使用“ALTER SYSTEM KILL SESSION”终止连接
  • 当连接池中存在连接而未用于 很长时间,由于执行的超时而断开连接 数据库(空闲时间)
  • 数据库重启
  • 网络事件已导致 要断开的连接,可能是因为网络已断开 不可用或防火墙已断开已断开的连接 开得太久了
  • 如果要设置
    InactivityTimeout
    ,则必须确保它小于数据库强制执行的
    空闲时间。您可以通过以下查询获得空闲时间

    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作为最小限制

    稍微重写一下您的配置文件会使它:

    <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>
    
    
    0
    200
    1.
    120
    180
    真的
    150
    

    当您尝试验证从池中获得的旧连接时,网络实际中断,您可能还会收到“无效或过时连接错误”。

    是的,我看到了错误

      java.sql.SQLException: Invalid or Stale Connection found in the Connection Cache. 
    
    切换到Oracle的ucp后,我再也没有看到任何过时的连接。我有如下设置

    <New id="DS" class="org.eclipse.jetty.plus.jndi.Resource">
        <Arg></Arg>
        <Arg>OracleDS</Arg>
        <Arg>
    
        <New class="oracle.ucp.jdbc.PoolDataSourceImpl">
                        <Set name="URL">jdbc:oracle:thin:@abc.corp.com:1234:xyz</Set>
                        <Set name="user">owner</Set>
                        <Set name="password”>pwd</Set>
                        <Set name="connectionFactoryClassName">oracle.jdbc.pool.OracleDataSource</Set>
                        <Set name="minPoolSize">0</Set>
                        <Set name="maxPoolSize">10</Set>
                        <Set name="inactiveConnectionTimeout">300</Set>
                        <Set name="maxStatements">200</Set>
                        <Set name="maxConnectionReuseCount">150</Set>
                        <Set name="connectionWaitTimeout">9</Set>
                        <Set name="abandonedConnectionTimeout">30</Set>
                        <Set name="validateConnectionOnBorrow">true</Set>
                        <Set name="SQLForValidateConnection">SELECT SYSDATE FROM DUAL</Set>
        </New>
    
        </Arg>
    </New>
    
    
    神谕
    jdbc:oracle:thin:@abc.corp.com:1234:xyz
    主人
    
    您正在重用连接句柄吗?尝试获取新的连接句柄连接句柄是什么?它与java一起使用吗?注意:我使用的是JDBC而不是ODBC谢谢我删除了connectionCachingEnabled属性并避免了这个问题。另外,请检查这对性能的影响,因为现在连接不会被缓存。您可能会为此考虑一个完整的连接池。