I was wondering whether finally block is really reliable to close the resource or not; such as, database connection?
According to our architect, finally block is not reliable to close the database connection especially in the web application scenario.
According to the theory, finally block must be run at the end of the logic flow no matter what is the execution status of the code. Finally block is the best practice.
I am working on web application project which is using JDK-1.4, plain SQL query and getting database connection from connection pooling. Most of the SQL statements are nested statements like, single method contains multiple Statement and ResultSet objects.
In this scenario, I am skeptical about finally block because according to the test, finally block is not releasing the resource instead the web app is acquiring more connection. At end, Tomcat 5.5 is hanged every two/three hours later.
Then, I removed the finally block and release the resource just after performing the SQL operation and in the catch block. After that, web app is releasing the resource perfectly and tomcat is not hanging anymore.
Therefore, I am really confused about the theory of finally block.
Here is the code snippet, please advise if coding technique is wrong:
... .. . . .. . .. . . .. .. .
........ . .. . . ... . .. . .
Connection dbCon = null;
Statement stmt1 = null;
ResultSet rs1 = null;
try {
dbCon = DB.getConnection();
stmt1 = dbCon.createStatement();
rs1 = stmt1.executeQuery("sql Query as String");
while(rs1.next()){
String col1 = rs1.getString("DB_COL_1");
int col2 = rs1.getInt("DB_COL_2");
String col3 = rs1.getString("DB_COL_3");
if(col3 != null){
Statement stmt2 = null;
ResultSet rs2 = null;
try{
stmt2 = dbCon.createStatement();
rs2 = stmt2.executeQuery("sql Query as String");
------- - ----
while(rs2.next()){
String col4 = rsTierMember.getString("DB_COL_4");
... . .. . . . .....
. .. . .. . . . . . ..
}
... . .. .. ... .
}catch(SQLException sqlExp){
} catch (Exception e) {
}finally{
try{
if(rs2!=null)
rs2.close();
if(stmt2!=null)
stmt2.close();
}catch(Exception ex){}
}
}
}
.... . .. .
}catch (SQLException e) {
} catch (Exception e) {
}finally{
try{
if(rs1!=null)
rs1.close();
if(stmt1!=null)
stmt1.close();
if(dbCon!=null)
dbCon.close;
}catch(Exception ex){
}
}
...... . . . . . ...
... . .. . .. . . .. .
It depends on what you mean by “reliable”.
tryblock hangs foreverIn all of these cases I’d expect the database to notice that the other end of the connection had gone away anyway.
If your architect has a specific scenario in mind where they believe the
finallyblock won’t execute, he should provide an example of that scenario, at which point you’ll almost certainly be able to prove them wrong. If they refuse to give any specifics, then ignore them, and suggest to management that they should start looking for a less superstitious architect.Sounds like the test is probably invalid, or you’re leaking connections elsewhere, or you’re not closing the connection. It’s easy to validate though: put logging in the
finallyblock, to validate that the code you expect to release the resource is at least being called. If it’s being called but not releasing the connection, then it’s no longer an issue aroundfinallyblocks.