0

我正在使用 c3p0 ComboPooledDataSource 来汇集数据库连接(到 Oracle 10g 数据库)。我在处理数据库连接中断时遇到问题。

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

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

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

这是线程转储

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

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

4

1 回答 1

1

我遇到了同样的问题。就我而言,这是由于 JDBC 驱动程序未设置为在套接字故障时超时所致。我在 C3P0ComboPooledDataSource配置中添加了以下内容:

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);
//--------------------------------------------------------------------------------------

...

Oracle 驱动程序属性在 C3P0 创建Connection对象时应用。如果套接字连接不活动超过 30 秒,这两个属性将导致抛出异常。

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

于 2015-02-10T18:20:55.910 回答