Should Connection (JDBS for SQL server) be closed strait away even if I intend on using it a moment later?
If I have a few methods in a Java class that both use Connection object, I create one connection, assign it as a property of the class, open and use the connection in first method (keep it open, do not .close() it)...don't use it for a moment (e.g. 10 seconds) then use the same open Connection again in a different method. Is this considered bad practice? i.e Should I close aftereach use? Seems very slow in doing so?
Related
I'm trying to figure out if there's a way to register to an auto-commit event.
Is there an observer? Perhaps I decorate an auto-commit connection or statement in order to be notified? What is the method to decorate?
I tried listening to Connection.commit() but it's not being invoked on statement executions.
Thanks. Alik.
auto-commit means that there is an implied commit at the end of each statement execution. As far as I know there is no event that you can listen to, and you cannot expect anyone to internally invoke Connection.commit(), because the auto-commit happens somewhere within the stack of the RDBMS that you are using, possibly even on the server.
So, in order to add an auto-commit event to JDBC you have to decorate every single function that may cause a statement to be executed, and see whether the SQL that was executed started with UPDATE, INSERT or DELETE verb. (Basically, anything but SELECT.)
The way I have decorated JDBC in the past is as follows:
Make a copy of every single JDBC interface, create a class out of it, create a concrete function for each method which delegates to a reference to a JDBC interface. Use lots of search-and-replace or possibly an editor that supports recording and replaying macros for that.
Define your own driver, and register it with JDBC, using your own driver name, like "jdbcdeco".
Establish the following convention: the connection string of your driver will be "jdbcdeco:" followed by the connection string of the driver that you want to decorate. So, if the connection string of the connection that you want to decorate is "jdbc:mysql://localhost/test" then the following connection string must be specified: "jdbc:jdbcdeco:mysql://localhost/test"
JDBC will instantiate your driver, and it will pass it the connection string, which begins with "jdbcdeco:". You strip away the "jdbcdeco:" part, and you are left with another connection string, which you use to pass again to JDBC in order to create the actual connection that is going to be decorated.
Good luck, and have fun!
Short answer- no such way exists to register to hear on auto commit. As mentioned in the answer by Mike, if you want to capture every commit you need to write custom code, you have to make the call whether you want to go through that much effort or not.
A simpler workaround would be to setAutoCommit as off on your connection but that is not what you have asked for :).
I have the following use case.
Our client app will make an API(this is me) call which returns a java resultset after executing a db call to the client app. I would like to know when the clients are done using the resultset so that I can close the resultset an the connection associated with it. So the design I thought was to send the resultset wrapped in an new object which has behaviors to close the resultset and the connection associated with it. This cleanup method has to be invoked by the client. Now, due to some reason if this cleanup method was never invoked by the client application, then we are going to endup with an open connection and un-freed DB resources. Is there a way to some how better monitor this and make sure all the DB resource are freed promptly. Additionally if there is any design pattern that might help in this use case please let me know.
Thanks.
Never return an expensive DB resource like a ResultSet to outside the API where you lose all the control. Instead map it to a List<Map<String, Object>> or something reuseable and return it.
one way would be to clean up the resultset/connection from the object using phantom references (I would prefer that over using finalize) - this way, you should be able to clean up the object and simply return it to the pool. Depending on your use case, you could look at timeouts as well.
Also, agreed with the other suggestion about not passing resultsets if possible.
hope it helps.
I want to close statement automatically.
I want to achieve it by the technology of the following conditions.
java1.5
spring framework2.5
It seems not to close automatically in the setting of default though I think that transaction manager of spring automatically shuts statement.
I do not want to call close() of statement as much as possible in the method for maintainability.
Is there a method of statement's closing?
Moreover, is there an official site or document that shows the reason when there is no closing method?
The amount of coding increases if coming for all the methods to have to call close() of statement, and there is a problem that the possibility that the omission is generated goes out.
Moreover, I am making the framework. It wants to make the restriction as much as possible by such a reason and to make a little method.
If I understood your question right you can use the http://commons.apache.org/dbcp/ to do the closing for you, as far as I know this is the standard anyway so most likely you are already using it, as long as you use spring or jndi to provide your database connectivity.
In your configuration for the database connection configure
removeAbandoned=true
and
removeAbandonedTimeout=50
See http://commons.apache.org/dbcp/configuration.html (the lowest block) for details.
Be aware that you should a rather large connection pool if you rely on it to clean up your connections.
To the question on why there is no closing method: there is.
For Connections: http://download.oracle.com/javase/6/docs/api/java/sql/Connection.html#close()
For Statements: http://download.oracle.com/javase/6/docs/api/java/sql/Statement.html#close()
For ResultSets: http://download.oracle.com/javase/6/docs/api/java/sql/ResultSet.html#close()
closing a Connection will close all its Statements.
closing a Statement will close all its ResultSets.
After all, its no good style to do so. I recommend calling the close() by yourself and use the abandonment removal only to find the places where you forgot to do so by adding
logAbandoned=true
We've found a bug in old code where connections aren't being closed. It's an easy fix, but I'm wondering how we go about proving that it's fixed. There is a choice of using a connection pool or not. For the pooling use it would be easy to add monitoring for the pool, but when connections pooling is not used, how do we track those unclosed, orphaned connections? Is it just like any other memory leak?
The bug looks like basically a cut and paste error. We have a few classes that manage the DB connection, so it looks roughly like this:
OurDBConn conn1 = ConnectionManager.getConnection();
try {
// business logic
} catch () {
//
} finally {
ConnectionManager.returnConnection(conn1);
}
/// and then later in the same method
OurDBConn conn2 = ConnectionManager.getConnection();
try {
// business logic
} catch () {
//
} finally {
ConnectionManager.returnConnection(conn1); // NOTE Error: conn1 should be conn2
}
I don't know why the earlier coders didn't just reuse the original connection, but that's what it is
(begin edit/append)
Yes, the connection code is ours as well and so I can use the answers given.
However, I don't think I asked the right question, although the answers below answer the question I asked. I'm not sure what the right stackoverflow thing to do is; ask another question, or edit this one?
One of the question I should have asked is: how would these orphaned, un-closed connections manifest themselves in system performance? Also, since these connection objects exist only within the scope of a certain method, wouldn't the connections be eligible for garbage collection? And then if they are gc'ed, what is the effect of open connections being gc'ed?
(end edit)
Assuming the connection manager is also your own code, you could store the initialised connections (along with a stacktrace) in a map within the connection manager, and then remove them when they are returned. Thus at any point, the keyset of the map is the set of unreturned connections, and you can look up that value in the map in order to find the guilty bit of code that created them and never released them. (If the connection isn't a suitable map key you can probably use some kind of unique ID or connection number or whatever - the actual value doesn't matter so much as its presence).
Then just add some appropriate way to access this map on demand and you're good. Depending on your environment, adding a shutdown hook that dump the contents of the map to a file, and/or adding a JConsole interface to lookup the set of unclosed connections in running code, could both be good options.
If the connection manager isn't your code, you could still probably achieve the same thing using aspects.
You can implement custom mini-framework or use exisitng one as a thin wrapper on JDBC operations. For example there is a spring-jdbc module (mavenized) that covers all of the boilerplate error-prone code from developer.
You can check its usage examples and see that there is no initialization/cleanup at the client code at all! It uses 'template method' pattern, i.e. you just write essential data processing and don't bother with connections/statements/resultsets creation and closing. So, it becomes not possible to introduce the problem you talked at first.
Currently what i am doing for transaction management is:
Connection connection = getConnection();
connection.setAutoCommit(false);
updateTableX ( connection, ... );
updateTableY ( connection, ... );
connection.commit();
closeConnection();
I would like to know, if it is possible to avoid closing the connection in my 'updateTableX' method. Because if someone accidentally closes the connection then my updateTableY will not be having the connection and it will throw the exception.
Just discipline. In general, methods shouldn't try to take responsibility for closing things passed into them as parameters - with the exception of situations where you create a new object to wrap an existing one.
The way to avoid closing the connection in updateTableX is just to make sure you don't put a call to close() into the code. This is no different than any other bug really. How do you stop updateTableX from arbitrarily updating a different table, or throwing an exception, or doing anything else it's not meant to? Code reviews, unit tests, integration tests, manual testing etc...
I mean you could write a Connection implementation which wraps another connection and proxies all the methods through except close() but it sounds like a waste of time - if you don't trust the developers involved not to close the connection, do you trust them to get the rest of the code right?
Like Jon said, if you really want to forbit to call close() you could write a decorator implementation that forwards to your "real" Connection object. I don't post a code example because the Connection interface is too big. With modern IDEs however it is no problem to generate the code.
Recipe (presuming you're using Eclipse):
Create a class that implements Connection, but do not implement the methods
Create a field private Connection delegate;
Select the field name -> Source (Menu) -> "Generate Constructor using fields" -> make sure the field is selected and press ok
Select the field name -> Source (Menu) -> "Generate Delegate Methods..." -> check every method on you field
Change the implementation of the close() method to throw an UnsupportedOperationException
However like Jon said, I would really think about doing something like that. And maybe you just use a Object-Relational-Mapper (e.g. Hiberate) to encapsulate all of your Database access logic. An additional very helpful framework in this area is Spring, especially if you do not want to care about Connection and DataSource handling.
(I am unfamiliar with Java specifically)
Assuming you have some sort of database managing object, you could have it make sure it is connected before it attempts any operations.
You could try to restrict access to closing the connection but how would you decide if it should be closed, or if it's "accidental" (however you define that)?
I don't think what you are asking is possible.
You can technically make a copy of your connection object, but then what happens if the client programmer doesn't close the connection?