0

谷歌返回了很多在 C3P0 中遇到死锁问题的人,但似乎没有一个解决方案适用(大多数人建议设置maxStatements = 0maxStatementsPerConnection = 0,我们都有这两个)。


我正在使用ComboPooledDataSource来自 C3P0 的,初始化为;

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 配置(几乎完全默认)可以在这里查看 -> 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);线路,一切都会顺利进行。关闭ResultSetConnection对象都可以正常工作 - 当然除了连接饥饿。

4

0 回答 0