Java 7 Automatic Resource Management JDBC (try-with-resources statement)

2022-09-01 05:21:31

如何将创建/接收连接、查询数据库并可能处理结果的常见 JDBC 习语与 Java 7 的自动资源管理(try-with-resources 语句)集成在一起?(教程)

在Java 7之前,通常的模式是这样的:

Connection con = null;
PreparedStatement prep = null;

try{
    con = getConnection();
    prep = prep.prepareStatement("Update ...");
    ...
    con.commit();
}
catch (SQLException e){
    con.rollback(); 
    throw e;
}
finally{
    if (prep != null)
        prep.close();
    if (con != null)
        con.close();
}

使用Java 7,您可以选择:

try(Connection con = getConnection(); PreparedStatement prep = con.prepareConnection("Update ..."){

   ...
   con.commit();
}

这将关闭 和 ,但是回滚呢?我无法添加包含回滚的 catch 子句,因为连接仅在 try 块中可用。ConnectionPreparedStatement

是否仍在 try 块之外定义连接?此处的最佳做法是什么,尤其是在使用连接池的情况下?


答案 1
try(Connection con = getConnection()) {
   try (PreparedStatement prep = con.prepareConnection("Update ...")) {
       //prep.doSomething();
       //...
       //etc
       con.commit();
   } catch (SQLException e) {
       //any other actions necessary on failure
       con.rollback();
       //consider a re-throw, throwing a wrapping exception, etc
   }
}

根据 oracle 文档,您可以将资源试用块与常规尝试块组合在一起。IMO,上面的例子捕获了正确的逻辑,即:

  • 尝试在没有任何问题时关闭预准备语句
  • 如果内部块出现问题,(无论是什么)回滚当前事务
  • 尝试关闭连接,无论发生什么
  • 如果关闭连接时出现问题,则无法回滚事务(因为这是连接上的方法,现在处于不确定状态),因此不要尝试

在java 6及更早版本中,我会使用一组三重嵌套的try块(外部try-finally,中间tried-catch,内部try-finally)来做到这一点。ARM语法确实使这更加简洁。


答案 2

IMO,在这种情况下,在尝试捕获之外声明连接和准备语句是可用的最佳方法。


推荐