谷歌在C3P0中返回了很多有死锁问题的人,但似乎没有一个解决方案适用(大多数人建议设置maxStatements = 0
和maxStatementsPerConnection = 0
,我们都有。{/ p>
我使用的是来自C3P0的ComboPooledDataSource
,初始化为;
cpds = new ComboPooledDataSource();
cpds.setDriverClass("org.postgresql.Driver");
cpds.setJdbcUrl("jdbc:postgresql://" + host + ":5432/" + database);
cpds.setUser(user);
cpds.setPassword(pass);
我的query
函数看起来像;
public static List<Map<String, Object>> query(String q) {
Connection c = null;
Statement s = null;
ResultSet r = null;
try {
c = cpds.getConnection();
s = c.createStatement();
s.executeQuery(q);
r = s.getResultSet();
/* parse result set into results List<Map> */
return results;
}
catch(Exception e) { MyUtils.logException(e); }
finally {
closeQuietly(r);
closeQuietly(s);
closeQuietly(c);
}
return null;
}
尽管query()
方法已到达return results;
行,但仍未返回任何查询。问题是finally
块正在挂起。我已经确定closeQuietly(s);
是无限期悬挂的线。
有问题的closeQuietly()
方法正如您所期望的那样;
public static void closeQuietly(Statement s) {
try { if(s != null) s.close(); }
catch(Exception e) { MyUtils.logException(e); }
}
为什么这种方法会挂在s.close()
上?我想这与我使用C3P0的方式有关。
我可以在这里查看完整的C3P0配置(几乎完全默认) - &gt; http://pastebin.com/K8XDdiBg
MyUtils.logException();
看起来像;
public static void logException(Exception e) {
StackTraceElement ste[] = e.getStackTrace();
String message = " !ERROR!: ";
for(int i = 0; i < ste.length; i++) {
if(ste[i].getClassName().contains("packagename")) {
message += String.format("%s at %s:%d", e.toString(), ste[i].getFileName(), ste[i].getLineNumber());
break;
}
}
System.err.println(message);
}
如果删除closeQuietly(s);
行,一切都会顺利进行。关闭ResultSet
和Connection
对象的工作都没有问题 - 当然除了连接饥饿之外。