When Using a thread-local database connection, closure of the connection is required when the thread exists.
This I can only do if I can override the run() method of the
I think in the general case there is no good solution for this, other than the classic: Code that gets the resource has to be responsible for closing it.
In the specific case, if you are calling threads to this degree you could pass in the connection to your methods at the start of the thread, either with a method that takes a custom parameter or via some form of Dependency Injection. Then since you have the code that supplies the connection, you have the code that removes it.
A Dependency Injection based on annotations might work here, as code that doesn't require the connection won't get one and therefore wouldn't need to be closed, but it sounds like your design is too far along to retrofit something like that.
The normal JDBC practice is that you close the Connection
(and Statement
and ResultSet
) in the very same method block as you'd acquired it.
In code:
Connection connection = null;
try {
connection = getConnectionSomehow();
// Do stuff.
} finally {
if (connection != null) {
try {
connection.close();
} catch (SQLException e) {
ignoreOrLogItButDontThrowIt(e);
}
}
}
Keeping this in mind, your question makes me think that there's something wrong in your design. Acquiring and closing those kind of expensive and external resources in the shortest scope will save the application from potential resource leaks and crashes.
If your original intent was to improve connecting performance, then you need to take a look for connection pooling. You can use for example the C3P0 API for this. Or if it's a webapplication, use the appserver's builtin connection pooling facilities in flavor of a DataSource
. Consult the appserver specific documentation for details.
I'm looking at the same problem. Looks like so far you have to use finalize(), though it is now deprecated. As the tasks are submitted to some Executor, you'd never know when a thread exactly exits, unless the Executor shows you, that means you have control of the Executor to some extend.
For example, if you build the Executor by extending ThreadPoolExecutor, you may override the afterExecution() and the terminated() methods to accomplish it. The former for a thread exiting abnormally while the latter for normally.