繁体   English   中英

Java 7 自动资源管理 JDBC(try-with-resources 语句)

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

如何使用 Java 7 的自动资源管理 try-with-resources 语句集成创建/接收连接、查询数据库和可能处理结果的通用 JDBC 习惯用法? 教程

在 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();
}

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

你还在try块之外定义连接吗? 这里的最佳实践是什么,尤其是在使用连接池的情况下?

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 文档,您可以将 try-with-resources 块与常规 try 块结合使用。 IMO,上面的示例捕获了正确的逻辑,即:

  • 如果没有任何问题,尝试关闭 PreparedStatement
  • 如果内部块出现问题,(无论是什么)回滚当前事务
  • 无论如何都要尝试关闭连接
  • 如果关闭连接时出现问题,则无法回滚事务(因为这是连接上的一种方法,现在处于不确定状态),所以不要尝试

在 java 6 及更早版本中,我将使用一组三重嵌套的 try 块(外部 try-finally、中间 try-catch、内部 try-finally)来执行此操作。 ARM 语法确实使这个更简洁。

IMO,在 try-catch 之外声明 Connection 和 PreparedStatement 是这种情况下可用的最佳方式。

如果你想在事务中使用池连接,你应该这样使用它:

try (Connection conn = source.getConnection()) {
        conn.setAutoCommit(false);
        SQLException savedException = null;
        try {
            // Do things with connection in transaction here...
            conn.commit();
        } catch (SQLException ex) {
            savedException = ex;
            conn.rollback();
        } finally {
            conn.setAutoCommit(true);
            if(savedException != null) {
                throw savedException;
            }
        }
    } catch (SQLException ex1) {
        throw new DataManagerException(ex1);
    }

此示例代码处理设置自动提交值。

注意,如果conn.rollback()抛出另一个异常,则使用savedException会保存异常。 这样,finally 块会抛出“正确”的异常。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM