接続の作成/受信、データベースへのクエリ、そしておそらく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();
}
これはConnection
とPreparedStatement
を閉じますが、ロールバックはどうですか?接続はtryブロック内でしか使用できないため、ロールバックを含むcatch句を追加できません。
まだ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は、正しいロジックをキャプチャします。
Java 6およびそれ以前のバージョンでは、トライブロックを入れ子にして入れ子にしたセット(外側のトライファイナル、中間のトライキャッチ、内側のトライファイナル)でこれを行います。)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);
}
_
このサンプルコードは、自動コミット値の設定を処理します。
注、savedException
を使用すると、conn.rollback()
が別の例外をスローした場合に備えて例外が保存されます。このように、最終的にブロックは「正しい」例外をスローします。