N Sharma
N Sharma

Reputation: 34507

Does it make a difference if I close the database connection after try/catch rather than in finally

In following two examples, I am 1) closing the database in the finally block and 2) closing it after the try ... catch. Does it make a difference which approach is used? If no, what is the point of finally, as we can release resources without using it?

try{
    // initialise a database connection
} catch (Exception e) {
    e.printStackTrace();
} finally{
    db.close
}

Second

try{
    // initialise a database connection
} catch (Exception e) {
    e.printStackTrace();
}
db.close

Upvotes: 0

Views: 960

Answers (4)

Stephen C
Stephen C

Reputation: 719606

One way to explain why finally is better / necessary is to point out the flaws in this version of the code:

try {
    // initialise a database
} catch (Exception e) {
    e.printStackTrace();
}
db.close();

The first problem is that if some exception that is a subtype of Error is thrown, then the try ... catch won't catch it. Error is a subtype of Throwable but not of Exception.

You might counter that one should not attempt to recover from an Error exception. That is true in many contexts, but not in others. For example, if this code was executed in a worker thread, a lot of frameworks will try to create a new thread to replace the one that died. That would result in the database handle leaking.

The second problem is that you are catching and squashing exceptions. Indeed, for the code as you have written it, you have to do this for the db.close() at the end to be executed. This might work in your example, but it won't work in general. For instance, what if you need to return something from this code ... or allow the exception to propagate for the caller to deal with.

The third problem is that you are catching Exception so that you can close db.close() in all cases. However, by doing this, you are most likely catching exceptions that should not be caught at this level. For example, if something withing the try block throws an NPE, you should not "squash and recover". Instead, you should allow the exception to propagate.

Note that using finally means that you don't have to worry about leakage in the case of Errors, recovering when you don't want to, or catching more exceptions than you mean to.

Now you can attempt to work around the three problems above without using finally, but it introduces other problems. (For example you could catch and then rethrow Exception with a db.close() in the handler, but then you would typically need to declare the enclosing method as throws Exception!)


Note that calling printStackTrace() like that is not advisable. A better approach is to use a logging framework ... so that the error reporting can be managed via a configuration file.

Upvotes: 3

John Czukkermann
John Czukkermann

Reputation: 625

It seems to me that the question is what is the difference between closing the database connection in the finally block versus after the finally block.

I will assume that the database was opened INSIDE the try block. If the code inside the try block threw an exception and your closed the database only after the finally block, you won't close the database when the exception is handled.

The correct way to do this is to close the database in the finally block. The finally block will run unconditionally, whether an exception was thrown or not.

Upvotes: 1

Fildor
Fildor

Reputation: 16148

Consider a little more specific example:

try{
    // initialise a database
} catch (SocketException e) {
    e.printStackTrace();
} finally{
    db.close
}

This will cleanup even if the exception was not a SocketException.

try{
    // initialise a database
} catch (SocketException e) {
    e.printStackTrace();
}
db.close

This won't. It will just bubble up the exception.

(I chose SocketException randomly. This of course goes as well for other Exceptions, Throwables etc)

Baseline: Using the finally block to perform clean-up fortifies your code against unexpected exceptions and exceptions thrown in your catch-blocks.

Upvotes: 0

Amit Bera
Amit Bera

Reputation: 7235

Finally, the block is a safe point to close the resource as finally block will execute in every situation until the System#exit called. It may happen that catch is also thrown an exception, in that case, your resource will not close if you put outside after catch block.

Upvotes: 1

Related Questions