【问题标题】:Tomcat JDBC - connection where SQLException happen not reused by poolTomcat JDBC - 发生 SQLException 的连接未被池重用
【发布时间】:2017-08-16 01:14:27
【问题描述】:

我为 PostgreSQL 使用 Tomcat JDBC 连接池。

池配置

<Resource name="jdbc/pg_mega" auth="Container"
        type="javax.sql.DataSource" driverClassName="org.postgresql.Driver"
        url="jdbc:postgresql://127.0.0.1:6432/db"
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory"
        username="***" password="****"
        defaultAutoCommit="true"
        initialSize="1"
        maxActive="300"
        maxTotal="300"
        maxIdle="20"
        minIdle="5"
        maxWait="10000"
        validationQuery="select 1"
        validationInterval="30000"
        testWhileIdle="false"
        testOnBorrow="true"
        testOnReturn="false"
        timeBetweenEvictionRunsMillis="30000"
        minEvictableIdleTimeMillis="30000"
        />

部分Java代码

Connection c = null;
Statement s = null;
ResultSet rs = null;
DataSource ds = ... Get DataSource  ...

while(running) {

    if (c == null) {
        try {
            c = ds.getConnection();
        } catch (SQLException exi) { env.l.pe(exi); }
    }
    try {
        s = c.createStatement();
        rs = s.executeQuery(q);
    } catch (SQLException sec) {
        // close resources
        if (rs != null) {
            try { rs.close(); } catch (SQLException sec2) { env.l.pe(sec2); }
            rs = null;
        }
        if (s != null) {
            try { s.close(); } catch (SQLException sec2) { env.l.pe(sec2); }
            s = null;
        }
        if (c != null) {
            try { c.close(); } catch (SQLException sec2) { env.l.pe(sec2); }
            c = null;
        }
        continue;
    }
    finally {
    ... close connection, statement, resultset...
    }
}

如果s.executeQuery(q) 时发生异常,我将关闭 Connection、Statement、ResultSet 并再次尝试连接(循环继续后)。

正如我在 JDBC 池活动中看到的,每次发生异常时活动连接都会增加。

你知道,我怎样才能释放以异常结束的池的数据库连接?

这可能是错误吗?

【问题讨论】:

  • 那么,您在catchfinally 中重复相同的关闭技术吗?为什么不直接使用try-with-resources?即try (c = ds.getConnection(); s = c.createStatement(); rs = s.executeQuery(q)) {...}
  • 我简化了代码。最初在 finally 部分中,如果尝试成功,则必须执行一些额外的代码。
  • 嗯,未正确关闭的连接可能导致此问题。
  • 我可能对池的使用不正确。

标签: java sql postgresql tomcat jdbc


【解决方案1】:

为什么要关闭 catch 中的连接?您可以/应该使用相同的连接并在最后关闭它,在 while 循环之外。

注意:如果您的查询格式不正确,或者如果您的数据库不可访问,您的代码可能会执行无限循环。

我建议您不要执行此 while 循环,只需重试 n 次(例如 3 次),每次尝试之间有一个等待时间。

【讨论】:

    猜你喜欢
    • 2011-06-15
    • 2015-12-26
    • 2010-12-24
    • 2012-03-02
    • 2013-05-01
    • 2014-12-26
    • 1970-01-01
    • 1970-01-01
    • 2012-07-12
    相关资源
    最近更新 更多