网络中断后C3P0连接未恢复,直到服务器重启

时间:2017-06-17 07:15:03

标签: java oracle connection-pooling c3p0

我们使用c3p0 ComboPooledDataSource与Spring JdbcTemplate进行连接池访问oracle 11g数据库。一段时间后(似乎在短暂的网络中断后),从池中获取连接的所有请求都将获得超时异常。在重新启动我们的weblogic服务器之前,这将无法解决(无需重新启动数据库服务器)。

Caused by: com.mchange.v2.resourcepool.TimeoutException: A client timed out while waiting to acquire a resource from com.mchange.v2.resourcepool.BasicResourcePool@a261ecc7 -- timeout at awaitAvailable()
    at com.mchange.v2.resourcepool.BasicResourcePool.awaitAvailable(BasicResourcePool.java:1317)
    at com.mchange.v2.resourcepool.BasicResourcePool.prelimCheckoutResource(BasicResourcePool.java:557)
    at com.mchange.v2.resourcepool.BasicResourcePool.checkoutResource(BasicResourcePool.java:477)
    at com.mchange.v2.c3p0.impl.C3P0PooledConnectionPool.checkoutPooledConnection(C3P0PooledConnectionPool.java:525)

我已检查过数据库当前会话以及c3p0日志,并且没有连接泄漏(仅使用50个1550连接)。 我还注意到,在网络中断之后,c3p0将不会获得新的连接(acquire_increment会增加,但是托管连接会从50减少到10)。

我们的数据源配置:

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
        <property name="properties" >
            <props>
                <prop key="oracle.net.CONNECT_TIMEOUT">20000</prop>
                <prop key="oracle.jdbc.ReadTimeout">70000</prop>
            </props>
        </property>
        <!-- Connection properties -->
        <property name="driverClass" value="oracle.jdbc.driver.OracleDriver"/>
        <property name="jdbcUrl" value="jdbc:oracle:thin:@//host:port/db_name"/>
        <property name="user" value="*****"/>
        <property name="password" value="*****"/>
        <!-- Pool properties -->
        <property name="testConnectionOnCheckout" value="true"/>
        <property name="checkoutTimeout" value="30000" />
        <property name="debugUnreturnedConnectionStackTraces" value="true" /> <!-- Turn this on only for debugging -->
        <property name="preferredTestQuery" value="select 1 from dual"/>
        <property name="initialPoolSize" value="3" />
        <property name="maxAdministrativeTaskTime" value="30" />
        <property name="maxIdleTime" value="600" />
        <property name="maxPoolSize" value="1550" />
        <property name="maxStatements" value="0" /> <!-- Disable statement pooling -->
        <property name="maxStatementsPerConnection" value="0" /> <!-- Disable statement pooling -->
        <property name="minPoolSize" value="5" />
        <property name="numHelperThreads" value="15" />
        <property name="unreturnedConnectionTimeout" value="600" /> <!-- Should set this for debugging leaks -->
    </bean>

我不知道到底发生了什么。

更新 对不起,已编辑的配置(测试在我的问题中是错误的,但在我的实际配置文件中没有)

1 个答案:

答案 0 :(得分:0)

一些事情:

  1. 您可能无法获得您认为自己的连接测试。您设置了一个名为TestConnectionOnCheckout的属性,但该属性的名称为testConnectionOnCheckout,小写为t
  2. 您可能有连接泄漏。 50是一个奇怪的圆形数量的繁忙连接,当你的应用程序冻结时,maxPoolSize 1550可能毫无意义,因为它高于你的后端支持。
  3. 您已配置unreturnedConnectionTimeoutdebugUnreturnedConnectionStackTraces来调试连接泄漏,但您的unreturnedConnectionTimeout非常长。事情冻结之后你必须等待10分钟才能观察(在你的日志中)任何最终泄露的Connections的签出堆栈痕迹。考虑在调试时将其缩小,例如30秒,这样就可以获得有关Connection泄漏的相当好的信息。
  4. 您将propertiesuserpassword设置为不同的值。那可能不是那么好。最终在JDBC属性中设置userpassword。如果在设置user属性之前设置了passwordproperties,则最终可能会使用身份验证凭据替换属性对象,并在没有正确用户和密码的情况下发出请求。如果您明确设置properties,请考虑使用类似......

    之类的内容
    <property name="properties" >
        <props>
            <prop key="oracle.net.CONNECT_TIMEOUT">20000</prop>
            <prop key="oracle.jdbc.ReadTimeout">70000</prop>
            <prop key="user">*****</prop>
            <prop key="password">*****</prop>
        </props>
    </property>
    
  5. ...因此您可以确定userpassword已设置。

    c3p0 PooledDataSources在池初始化时将其配置记录在INFO中。可能值得一看,并验证它是您期望看到的配置。