当网络出现故障时,c3p0会在getConnection上挂起

时间:2013-10-21 09:27:56

标签: oracle jdbc connection-pooling c3p0

我正在使用c3p0 ComboPooledDataSource来池化数据库连接(到Oracle 10g数据库)。我在处理数据库连接中断方面遇到了问题。

如果在获取第一个连接时没有与数据库的连接,则结帐超时会触发,并且会按预期失败。

但是,如果在获取一个或多个连接并且已经在连接池中之后发生连接中断,则调用getConnection()只会挂起。没有异常被抛出。我猜这是因为它试图使用池连接,但该连接不再存在。

有没有办法在尝试使用之前检查连接是否有效?我尝试设置testConnectionOnCheckout = true但它似乎没有任何效果。

这是线程转储

C3P0PooledConnectionPoolManager [identityToken-> 2rvy8f8x1oujxrx1majv5s | be41d5] - HelperThread-#2“daemon prio = 6 tid = 0x0307a800 nid = 0x840 in Object.wait()[0x03d1f000]     java.lang.Thread.State:TIMED_WAITING(在对象监视器上)     在java.lang.Object.wait(Native Method) - 等待< 0x28387f88> (com.mchange.v2.async.ThreadPoolAsynchronousRunner)     在com.mchange.v2.async.ThreadPoolAsynchronousRunner $ PoolThread.run(ThreadPoolAsynchronousRunner.java:635)      - 已锁定< 0x28387f88> (com.mchange.v2.async.ThreadPoolAsynchronousRunner)

锁定可拥有的同步器:      - 没有

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题。在我的情况下,它是由于JDBC驱动程序未在套接字故障时设置为超时而引起的。我对我的C3P0 ComboPooledDataSource配置进行了以下添加:

cpds = new ComboPooledDataSource();
...

//--------------------------------------------------------------------------------------
// NOTE: Once you decide to use cpds.setProperties() to set some connection properties,
//       all properties must be set, including user/password, otherwise an exception
//       will be thrown
Properties prop = new Properties();
prop.setProperty("oracle.net.CONNECT_TIMEOUT",
    Integer.toString(JDBC_CONNECTION_TIMEOUT_IN_MILLISECONDS));
prop.setProperty("oracle.jdbc.ReadTimeout",
    Integer.toString(JDBC_SOCKET_TIMEOUT_IN_MILLISECONDS));
prop.setProperty("user", username);
prop.setProperty("password", password);
cpds.setProperties(prop);
//--------------------------------------------------------------------------------------

...

当C3P0创建Connection对象时,将应用Oracle驱动程序属性。特别是这两个属性将导致在套接字连接处于非活动状态超过30秒时抛出异常。

如果您没有连接到Oracle数据库,则其他数据库供应商的其他JDBC驱动程序也有类似的属性。其中一些显示在this page的底部附近。