我正在使用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)
锁定可拥有的同步器: - 没有
答案 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的底部附近。