- PR -

tryの中でjsp:forwardを実行した場合、finallyの中の処理は実行されるのか

1
投稿者投稿内容
ma2
会議室デビュー日: 2008/09/09
投稿数: 6
投稿日時: 2008-09-09 16:23
現在、tomcatとmysqlを連携したwebシステムを作っているのですが、tryの中でjsp:forwardを実行した場合、finallyの中の処理は実行されるのかどうか、わかる方はいらっしゃいますでしょうか?

具体的には、データベースとの接続をtry catchで行い、finallyの中でデータベースのcloseをしているのですが、ログイン認証などでユーザーがいない(レコードが0)とわかった瞬間、try文の中でjsp:forwardを実行し別ページへ飛ばす処理をしており、この場合だとconnectionが閉じられていないまま別ページへ遷移しているのでは、、という不安に襲われました。

本来であれば、forwardの処理をtryの外へ出し、connectionが確実に閉じられたあとにforwardするのが正しいと思うのですが、プログラムの枚数の関係上、現状維持で問題なければそのままにしておきたい(修正が非常に困難)と思い、質問をいたします。

わかりにくい質問で申し訳ございませんが、よろしくお願いいたします。
以下、実際のプログラムです。

Connection connection1=null;
Statement statement1=null;
ResultSet rs=null;

try {
InitialContext initCon = new InitialContext();
DataSource ds = (DataSource)initCon.lookup("java:comp/env/jdbc/MySQL_test");
connection1 = ds.getConnection();

statement1=connection1.createStatement();

//ユーザーIDとパスワードからユーザーが存在するか認証
String qStr="SELECT COUNT(*) AS numberOfPerson FROM user WHERE name='"+ユーザーID+"' AND password='"+パスワード+"'";
rs=statement1.executeQuery(qStr);
rs.next();
int np=rs.getInt("numberOfPerson");
rs.close();
rs=null;

//ユーザーが0の場合
if(np == 0) {
%>
<jsp:forward page="test.jsp"/>
<%
}

statement1.close();
statement1=null;
connection1.close();
connection1=null;

} catch (SQLException ex) {
ex.printStackTrace ();
throw ex;
} catch (Exception ex) {
ex.printStackTrace ();
throw ex;
} finally {
// データベースへの接続をクローズ
try {
if (rs!=null) {
try {
rs.close();
} catch(Exception e){
}
rs=null;
}
if (statement1!=null) {
try {
statement1.close();
} catch(Exception e){
}
statement1=null;
}
if (connection1!=null) {
try {
connection1.close();
} catch(Exception e){
}
connection1=null;
}
} catch (Exception ex) {
ex.printStackTrace();
throw ex;
}
}
この状態でforwardされた場合、きちんとconnectionやstatementが閉じられているのか、教えていただけるとありがたいです。

[ メッセージ編集済み 編集者: ma2 編集日時 2008-09-09 16:25 ]
わたなべ
大ベテラン
会議室デビュー日: 2007/12/09
投稿数: 123
お住まい・勤務地: 札幌
投稿日時: 2008-09-09 16:58
コードが正しいか否かはわかりませんし、読むのもダルいコードなんで確認していません。
ですが、コードを正しく書いてあれば、finallyは必ず実行されます。
不安なのであれば、ログを出力するなりして確認してはどうです?

#まさかとは思いますが、これ、業務アプリじゃないですよね・・・
mio
ぬし
会議室デビュー日: 2005/08/25
投稿数: 734
お住まい・勤務地: 神奈川県
投稿日時: 2008-09-09 17:14
例えばSystem.out.println("hoge");などfinally句に入れるだけで、通るかどうかの確認はできます(Tomcatのログに出てきます)。

一部の実行環境に起因するエラー(依存先で必要なクラスがないとか)の場合、finallyに来ずにすぱっと落ちてしまう場合もありますが、それはロジック以前の話ですね。

ただ、普通は(認識されているように)DBのロジックとforwardは切り分けるべきですね。
forwardの処理が終わるまで、不必要なConnectionを持ったままになるし。

[ メッセージ編集済み 編集者: mio 編集日時 2008-09-09 17:15 ]
ma2
会議室デビュー日: 2008/09/09
投稿数: 6
投稿日時: 2008-09-09 20:55
わたなべ様

ご回答ありがとうございます。
ログの出力等、まだまだ力不足で発想もありませんでした。
当面はわたなべ様の「finallyは必ず実行される」と言葉を信じたいと思います。
(このコードが正しければ、ですが・・・)

実際、このコードはまさかの業務アプリだったりします。。
恥を忍んでお聞きしたいのですが、やはりこのコードでは業務アプリとしてはダメダメなんでしょうか…。
独学でスタートし、プロの方に見て頂けることなく今に至ってしまったため、このような事態となってしまいました。

お言葉を受け止め、粛々と一から学び直すつもりですので、具体的にダメなところを教えて頂けると嬉しいです。

すいません、最後悩み相談のようになってしまいましたが、、、ご回答どうもありがとうございました!
ma2
会議室デビュー日: 2008/09/09
投稿数: 6
投稿日時: 2008-09-09 21:06
mio様

ご回答ありがとうございます。

具体的にはforwardで飛ばされたページの処理が終わった後、finallyが実行される、と認識したのですが、、、それが正しいかはもう一度勉強して確認します。

やはりConnectionを持ったままでいるのはよくないのですね。そこはお言葉を受け止め見直して行きます。
未熟で、どうなのだろうと悩んでたので、本当に助かりました。どうもありがとうございました!
1

スキルアップ/キャリアアップ(JOB@IT)