37

接続の作成/受信、データベースのクエリ、およびおそらく結果の処理という一般的な 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();
}

Connectionこれでとが閉じますPreparedStatementが、ロールバックはどうでしょうか。接続は try ブロック内でのみ使用できるため、ロールバックを含む catch 句を追加できません。

try ブロックの外側でまだ接続を定義していますか? 特に接続プールが使用されている場合、ここでのベストプラクティスは何ですか?

4

3 に答える 3

40
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
   }
}

オラクルのドキュメントによると、try-with-resources ブロックを通常の try ブロックと組み合わせることができます。IMO、上記の例は正しいロジックをキャプチャします。つまり、次のとおりです。

  • 何も問題がなければ、PreparedStatement を閉じようとします
  • 内側のブロックで何か問題が発生した場合、(何が何であれ) 現在のトランザクションをロールバックします
  • 何があっても接続を閉じようとする
  • 接続を閉じる際に何か問題が発生した場合、トランザクションをロールバックすることはできません (これは現在不確定な状態にある接続上のメソッドであるため)。

Java 6 以前では、3 重にネストされた一連の try ブロック (外側の try-finally、中間の try-catch、内側の try-finally) を使用してこれを行います。ARM 構文はこれをより簡潔にします。

于 2012-02-13T12:31:51.233 に答える
4

この場合、IMO、try-catchの外部でConnectionとPreparedStatementを宣言することが、利用可能な最良の方法です。

于 2012-02-13T12:07:52.553 に答える