I was reading my database access logic, and found that it was possible for the same connection to be closed twice in a row.
Other than being a duplicate instruction, is there any reason I should be concerned about closing a connection after it's already been closed?
If you are using the java.sql.Connection you should have no issue.
From the Connection documentation:
Calling the method close on a Connection object that is already closed
is a no-op.
i.e. it does nothing.
This should stand for any proper implementation. Although it is conceivable for some implementation to have odd behavior on this matter.
From the documentation:
Releases this Connection object's database and JDBC resources
immediately instead of waiting for them to be automatically released.
Calling the method close on a Connection object that is already closed
is a no-op. It is strongly recommended that an application explicitly
commits or rolls back an active transaction prior to calling the close
method. If the close method is called and there is an active
transaction, the results are implementation-defined.
So in short it is supposed to do nothing. Be aware though that a sloppy implementation for this Connection interface might fail to meet the rules defined in this interface's contract. You did not say which database are you using so I cannot provide further information on the implementation details.
Related
I asked this question (How do I call java.sql.Connection::abort?) and it led me to another question.
With
java.sql.Connection conn = ... ;
What is the difference between
conn.close();
and
conn.abort(...);
?
You use Connection.close() for a normal, synchronous, close of the connection. The abort method on the other hand is for abruptly terminating a connection that may be stuck.
In most cases you will need to use close(), but close() can sometimes not complete in time, for example it could block if the connection is currently busy (eg executing a long running query or update, or maybe waiting for a lock).
The abort method is for that situation: the driver will mark the connection as closed (hopefully) immediately, the method returns, and the driver can then use the provided Executor to asynchronously perform the necessary cleanup work (eg making sure the statement that is stuck gets aborted, cleaning up other resources, etc).
I hadn't joined the JSR-221 (JDBC specification) Expert Group yet when this method was defined, but as far as I'm aware, the primary intended users for this method is not so much application code, but connection pools, transaction managers and other connection management code that may want to forcibly end connections that are in use too long or 'stuck'.
That said, application code can use abort as well. It may be faster than close (depending on the implementation), but you won't get notified of problems during the asynchronous clean up, and you may abort current operations in progress.
However keep in mind, an abort is considered an abrupt termination of the connection, so it may be less graceful than a close, and it could lead to unspecified behaviour. Also, I'm not sure how well it is supported in drivers compared to a normal close().
Consulting the java docs seems to indicate that abort is more thorough than close, which is interesting.
abort...
Terminates an open connection. Calling abort results in: The
connection marked as closed Closes any physical connection to the
database Releases resources used by the connection Insures that any
thread that is currently accessing the connection will either progress
to completion or throw an SQLException.
close...
Releases this Connection object's database and JDBC resources
immediately instead of waiting for them to be automatically released.
Calling the method close on a Connection object that is already closed
is a no-op.
So it seems if you are only concerned with releasing the objects, use close. If you want to make sure it's somewhat more "thread safe", using abort appears to provide a more graceful disconnect.
Per Mark Rotteveel's comment (which gives an accurate summary of the practical difference), my interpretation was incorrect.
Reference: https://docs.oracle.com/javase/8/docs/api/java/sql/Connection.html#close--
I am working on some old code and i found that the jdbc connection is being passed on as parameter of a method from one class to another.
When the application is run, jdbc connection leaks are observed. The connection is being closed in the same function from where it is being passed.
Should the connection be closed in every method in which it is being passed as a parameter ?
If it is not required, then can i set the connection to null in every method ? Or please suggest if there is any other way to clear connection leaks.
You must ensure the connection is closed in the same method that opens it. Nothing else will work. The connection should be closed in a finally block to ensure it happens.
Can I set the connection to null in every method?
Only if you like writing pointless code. Setting things to null doesn't close anything, or cure connection leaks, or indeed accomplish anything at all in the case of parameters to a method which is about to exit.
yes definitely you have to close the connection in each method. if your project architecture is mvc. you have some DAO classes in the classes you have the persistence logic. so before closing the connection make sure that the connection is alive or not, make a condition like.
if(connection!=null) {
connection.close();
}
This question already has answers here:
Must JDBC Resultsets and Statements be closed separately although the Connection is closed afterwards?
(12 answers)
Closed 9 years ago.
I know the safe pattern in Java is to close your ResultSet, Statement, and Connection in order in a finally block.
If you close connection and then try to close statement(doesnt throw exception). But if you try to call any method from statement an exception is thrown.
I was wondering does closing connection automatically close all the statement objects created out of that connection?
Update:
I am using DatabaseProductVersion: Oracle Database 11g Release 11.1.0.0.0
DriverName: Oracle JDBC driver
DriverVersion: 10.2.0.4.0
Yes it does, Connection.close API says "Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically released". The problem is that applications typically use database connection pools and these may simply return Connection to pool on Connection.close.
In any case, it's a good practice to always close ResultSet and Statement explicitly and not to rely on Connection.close.
Besides, it's not the best idea to work with JDBC directly. You can use Spring JDBC instead and forget about releasing resources problem.
The details are ultimately down to each JDBC driver implementation; however, once a connection to the database is closed, everything related to it is disposed at the DB side, so there is nothing much the client side can do but auto-close the objects representing these resources.
You never know in what ways the databeses/drivers could be broken (there may be resource leaks, for example), therefore the best practice recommendation is to close everything explicitly.
Let's say I get a PreparedStatement from a Connection object, and then later I overwrite the reference with another PreparedStatement. Then, later, I close() the reference. Will the first PreparedStatement (the one I lost the reference to) remain open? Or does some protocol or garbage collection take care of that?
For example:
PreparedStatement ps = connection.prepareStatement(MY_QUERY);
// do stuff
ps.execute();
ps = connection.prepareStatement(MY_OTHER_QUERY);
// do stuff
ps.execute();
ps.close();
Does the first PreparedStatement object, the one used to execute MY_QUERY, remain open?
Yes, the PreparedStatement will be left open until it gets garbage collected* (if at all).
That's why you always see the rule to always release (close) external resources that you acquire.
JDBC resources (such as this prepared statement, connections, results sets) and IO resources (sockets, streams, ...) are the two most common resources that you manually need to manage in Java.
* strictly speaking it could be closed in the finalize method which could be slightly before it gets GCed, but after it becomes eligible for the GC, but for this discussion this is close enough.
It'll be closed when the object is eventually garbage collected. Since you have little control over the garbage collection process, it is a good idea to close statements as soon as you're done with them.
From the documentation for Statement.close():
Releases this Statement object's database and JDBC resources immediately instead of waiting for this to happen when it is automatically closed. It is generally good practice to release resources as soon as you are finished with them to avoid tying up database resources.
It will stay open, and there is no guarantee that it will be closed when garbaged collected. It depends on implementation. Implementation needs to override finalize like in eg FileInputStream.finalize which
"...ensures that the close method of this file input stream is called when there are no more references to it."
But Connection.close can close PreparedStatement, see API for Connection.close:
"..releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically released.."
but only if it is not pooled Connection.
Hello i am trying to implement a database-object("connection") pooler for BerkeleyDB...
I decided to use a singleton EJB propably or ENUM singleton implementation for this..
A final concurrenthash map would store database objects with a timestamp...
the method getConnection() would use double check locking as long as the value from map is volatile. - No performance issues i believe..(Java Connection Pooler getConnection is synchronized!!)
The database is spread into 100 files + the daily ones.. (application designed in mid seventies 1976)..
So far everything is fine... But i want to close daily unused handles.
So i decided to use a Timer to run every 24 hours a cleanup routine..
The problem is that how can i ensure that during cleanup a connection to be closed isnt requested ?
Pseudo algorithm
cleanup(){
for(Database db in map){
if(db.getLastAccess - now >24hours) {
res=map.remove("key",db);
db.close();
}
}
}
i know that the above isnt thread safe..How could i block getconnection ? Because many things could go wrong... "If condition" may be true but before removing db obj getLastAccess could be changed! Cleanup would be called by single thread though..
Is there any solution to block getconnection somehow so cleanup to work or anyother solution?
I am not sure if you currently do this, but if you have a way to determine if a connection is in use this would make this slightly easier. One thing that you can do, is iterate over the connections in your pool. When you find one that matches your criteria for being closed, try to mark it as being in use (assuming that a connection that is in use will not be returned as a open connection). If you succeed, close it. Otherwise, check it until it becomes free and you are able to mark it as being in use. Once you have been able to do this, you should be able to close it.
Each connection would have a lock associated with it, in order for the connection to be returned by the getConnection method, the correct lock would have to be acquired. The cleanup method would also need to acquire the lock before closing a connection. Take a look at the java.util.concurrent.lock package.
Maybe a Semaphore is a better solution. Follow the link for an example.
I've never worked with BerkeleyDB, but I assume it has a JDBC interface. Can't you use an out of the box solution like DBCP or c3p0? Also check the Pool Component, it is a generic pool interface.