【问题标题】:Which should I close first, the PreparedStatement or the Connection?我应该先关闭哪个,PreparedStatement 还是 Connection?
【发布时间】:2011-01-22 18:08:31
【问题描述】:

在 JDBC 中使用PreparedStatement 时,我应该先关闭PreparedStatement 还是先关闭Connection?我刚刚看到一个代码示例,其中首先关闭了Connection,但在我看来,首先关闭PreparedStatement 似乎更合乎逻辑。

是否有标准的、可接受的方式来执行此操作?有关系吗?关闭Connection 是否也会导致关闭PreparedStatement,因为PreparedStatementConnection 对象直接相关?

【问题讨论】:

  • 虽然根据规范,当连接关闭时该语句应该被关闭,但 JDBC 驱动程序已经看到有这个问题,因此显式关闭语句被认为是一种好习惯(以及结果设置)。
  • 按照打开它们的相反顺序关闭它们。所有的东西。

标签: java jdbc connection prepared-statement


【解决方案1】:

声明。我希望你关闭(按顺序)

  1. 结果集
  2. 声明
  3. 连接

(并一路检查空值!)

即以反向顺序关闭。

如果您使用 Spring JdbcTemplate(或类似的),那么它将为您解决这个问题。或者,您可以使用Apache Commons DbUtilsDbUtils.close()DbUtils.closeQuietly()

【讨论】:

  • 确实如此。某些 JDBC 驱动程序会在连接关闭后关闭结果集或语句时抛出异常。
  • 没错。重点:在获得它们时以相反的顺序关闭资源
【解决方案2】:

以下程序应(按顺序)完成

  • ResultSet
  • PreparedStatement
  • Connection

另外,建议关闭finally close 中的所有 JDBC 相关对象以保证关闭。

//Do the following when dealing with JDBC. This is how I've implemented my JDBC transactions through DAO....

Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;

try {
  conn = ....
  ps = conn.prepareStatement(...);

  //Populate PreparedStatement
  rs = ps.executeQuery();

} catch (/*All relevant exceptions such as SQLException*/Exception e) {
  logger.error("Damn, stupid exception: " , e);
} finally {
if (rs != null) {
            try {
                rs.close();
                rs = null;
            } catch (SQLException e) {
                logger.error(e.getMessage(), e.fillInStackTrace());
            }
        }

        if (ps != null) {
            try {
                ps.close();
                ps = null;
            } catch (SQLException e) {
                logger.error(e.getMessage(), e.fillInStackTrace());
            }
        }

        try {
            if (conn!= null && !conn.isClosed()){
                if (!conn.getAutoCommit()) {
                    conn.commit();
                    conn.setAutoCommit(true);
                }
                conn.close();
                conn= null;
            }
        } catch (SQLException sqle) {
            logger.error(sqle.getMessage(), sqle.fillInStackTrace());
        }
}

您可以看到我已经检查了我的对象是否为空,对于连接,如果连接没有自动提交,请检查首先。许多人没有检查它并意识到该事务尚未提交给 DB。

【讨论】:

  • 所有最终样板文件都应该被压缩成一个实用方法(例如DBUtils.close(rs, ps, conn);)。此外,关于自动提交的建议取决于具体情况。有时,当您根本不想提交异常时。此外,几乎总是不需要显式设置对 null 的引用,因为它会在方法退出时被取消引用,希望在此之后很快,否则方法可能太长了。
  • @Yishai,是的,我忘了说如果有异常并且自动提交关闭,你可以做一个回滚......谢谢你展示这个。
猜你喜欢
  • 2016-09-14
  • 1970-01-01
  • 1970-01-01
  • 2010-11-02
  • 2010-10-17
  • 1970-01-01
  • 2011-06-19
  • 2017-12-23
  • 1970-01-01
相关资源
最近更新 更多