我们使用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>
我不知道到底发生了什么。
更新 对不起,已编辑的配置(测试在我的问题中是错误的,但在我的实际配置文件中没有)
答案 0 :(得分:0)
一些事情:
TestConnectionOnCheckout
的属性,但该属性的名称为testConnectionOnCheckout
,小写为t
。maxPoolSize
1550可能毫无意义,因为它高于你的后端支持。unreturnedConnectionTimeout
和debugUnreturnedConnectionStackTraces
来调试连接泄漏,但您的unreturnedConnectionTimeout
非常长。事情冻结之后你必须等待10分钟才能观察(在你的日志中)任何最终泄露的Connections的签出堆栈痕迹。考虑在调试时将其缩小,例如30秒,这样就可以获得有关Connection泄漏的相当好的信息。您将properties
,user
和password
设置为不同的值。那可能不是那么好。最终在JDBC属性中设置user
和password
。如果在设置user
属性之前设置了password
和properties
,则最终可能会使用身份验证凭据替换属性对象,并在没有正确用户和密码的情况下发出请求。如果您明确设置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>
...因此您可以确定user
和password
已设置。
c3p0 PooledDataSources在池初始化时将其配置记录在INFO中。可能值得一看,并验证它是您期望看到的配置。