Java 7自动资源pipe理JDBC(试用资源语句)

如何整合创build/接收连接的常见JDBC习惯用法,查询数据库并可能使用Java 7的自动资源pipe理,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(); } 

这将closuresConnectionPreparedStatement ,但是回滚呢? 我不能添加包含回滚的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块结合起来。 国际海事组织,上面的例子捕捉正确的逻辑,这是:

  • 如果没有出错,尝试closuresPreparedStatement
  • 如果内部块发生错误,(不pipe是什么)回滚当前事务
  • 尝试closures连接,无论如何
  • 如果closures连接出现问题,则无法回滚事务(因为这是连接上的方法,现在处于不确定状态),所以不要尝试

在Java 6和更早的版本中,我将使用三重嵌套的try块(外部try-finally,中间try-catch,内部try-finally)来做到这一点。 ARM语法确实使这个问题变得更加严峻。

国际海事组织,声明连接和PreparedStatement外try-catch是在这种情况下可用的最佳方式。

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

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

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