c3p0 hangs on getConnection when there is a network failure

送分小仙女□ 提交于 2019-12-12 02:41:02

问题


I'm using c3p0 ComboPooledDataSource to pool database connections (to an Oracle 10g database). I'm having problems with handling database connectivity outages.

If there is no connection to the database when the first connection is being acquired, the checkout timeout fires and it fails as expected.

However, if a connection outage occurs after one or more connections have been acquired and are already in the connection pool, calling getConnection() just hangs. No exception is thrown. I'm guessing this is because it's trying to use a pooled connection but that connection is no longer alive.

Is there a way to check whether the connection is valid before trying to use it? I tried setting testConnectionOnCheckout=true but it doesn't seem to have any effect.

This is the thread dump

C3P0PooledConnectionPoolManager[identityToken->2rvy8f8x1oujxrx1majv5s|be41d5]- HelperThread-#2" daemon prio=6 tid=0x0307a800 nid=0x840 in Object.wait() [0x03d1f000] java.lang.Thread.State: TIMED_WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x28387f88> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner) at com.mchange.v2.async.ThreadPoolAsynchronousRunner$PoolThread.run(ThreadPoolAsynchronousRunner.java:635) - locked <0x28387f88> (a com.mchange.v2.async.ThreadPoolAsynchronousRunner)

Locked ownable synchronizers: - None


回答1:


I encountered the same issue. In my case, it was caused by the JDBC driver not being setup to timeout on socket failures. I made the following additions to my C3P0 ComboPooledDataSource configuration:

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

...

The Oracle driver properties are applied when C3P0 creates the Connection object. These two properties in particular will cause an exception to be thrown if the socket connection is inactive for more than 30 seconds.

If you're not connecting to an Oracle database, there are similar properties for other JDBC drivers for other database vendors. Some of them are shown near the bottom of this page.



来源:https://stackoverflow.com/questions/19490719/c3p0-hangs-on-getconnection-when-there-is-a-network-failure

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!