首页 文章

关闭池中的JDBC连接

提问于
浏览
96

我们使用JDBC的标准代码部分是......

Connection conn = getConnection(...);
Statement  stmt = conn.conn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE,
                                                ResultSet.CONCUR_READ_ONLY);
ResultSet  rset = stmt.executeQuery (sqlQuery);

// do stuff with rset

rset.close(); stmt.close(); conn.close();

问题1:使用连接池时,是否应该在结束时关闭连接?如果是这样,汇集失败的目的不是?如果没有,DataSource如何知道什么时候释放Connection的特定实例并且可以重用?我对这个有点困惑,任何指针都赞赏 .

问题2:以下方法是否接近标准?看起来像是尝试从池中获取连接,如果无法 Build DataSource,请使用旧式的DriverManager . 我们甚至不确定哪个部分在运行时被执行 . 重复上面的问题,是否应该关闭Connection这样的方法?

谢谢, - MS .

synchronized public Connection getConnection (boolean pooledConnection)
                                                        throws SQLException {
        if (pooledConnection) {
                if (ds == null) {
                        try {
                                Context envCtx = (Context)
                                        new InitialContext().lookup("java:comp/env");
                                ds = (DataSource) envCtx.lookup("jdbc/NamedInTomcat");
                                return ds.getConnection();
                        } catch (NamingException e) {
                                e.printStackTrace();
                }}
                return (ds == null) ? getConnection (false) : ds.getConnection();
        }
        return DriverManager.getConnection(
                "jdbc:mysql://"+ipaddy+":"+dbPort +"/" + dbName, uName, pWord);
}

编辑:我认为我们正在获得池连接,因为我们没有看到堆栈跟踪 .

3 回答

  • 106

    使用连接池时,是否应该在结束时关闭连接?如果是这样,汇集失败的目的不是?如果没有,DataSource如何知道什么时候释放Connection的特定实例并且可以重用?我对这个有点困惑,任何指针都赞赏 .

    是的,当然你也需要关闭池化连接 . 它进一步到池,以决定实际连接是否将实际关闭或重新用于新的 getConnection() 调用 . 因此,无论您是否使用连接池,都应该 alwaystry 块的 finally 块中以相反的顺序关闭所有JDBC资源 . 在Java 7中,可以使用try-with-resources语句进一步简化此操作 .


    以下方法是否接近标准?看起来像是尝试从池中获取连接,如果无法 Build DataSource,请使用旧式的DriverManager . 我们甚至不确定哪个部分在运行时被执行 . 重复上面的问题,是否应该关闭Connection这样的方法?

    这个例子非常可怕 . 您只需要在应用程序启动期间在应用程序范围的DB配置类的某些构造函数/初始化中查找/初始化 DataSource . 然后在应用程序的整个生命周期中,在同一个数据源上调用 getConnection() . 无需同步或无需检查 .

    另见:

  • 0

    这些池通常会返回一个包装的Connection对象,其中覆盖了close()方法,通常会将Connection返回到池中 . 调用close()是可以的,可能仍然需要 .

    close()方法可能如下所示:

    public void close() throws SQLException {
      pool.returnConnection(this);
    }
    

    对于第二个问题,您可以添加一个 Logger 来显示底部块是否运行 . 我想,虽然你只想要一种方法来配置你的数据库连接 . 我们只使用池来进行数据库访问 . 无论哪种方式,关闭连接对于防止泄漏非常重要 .

  • 21

    实际上,连接管理的最佳方法是不要将它们分配到任何地方的任何代码 .

    创建一个SQLExecutor类,它是打开和关闭连接的唯一位置 .

    然后,应用程序的其余部分将语句泵入执行程序,而不是从池中获取连接并在整个地方管理(或管理不当) .

    您可以根据需要拥有尽可能多的执行程序实例,但是没有人应该编写代表自己打开和关闭连接的代码 .

    方便的是,这也允许您从一组代码中记录所有SQL .

相关问题