Proper use of close() and = null for Closable objects - java

Say, I'm using connection to database named con (or socket or anything else which is Closable). What happens after close()? Does con become equal to null or there is still something in it? And what is the difference between con.close() and con = null?

When you call close, the object should free all the resources it uses behind the scenes. In case of an instance of java.sql.Connection, it will one of two things:
Free any physical connection to the database, thus freeing resources. This happens when you open a database connection manually e.g. DriverManager.getConnection(...).
Go into a SLEEPING state and wait to be invoked again. This happens when the Connection is handled by a DataSource which is handled by a database connection pool.
Setting the object con = null just assigns null value to a variable, the reference will still be alive until the Garbage Collector decides to remove it. Still, setting the Connection to null doesn't call close method, thus you can have memory leaks.
As a best practice, you should ALWAYS call close method on instances of Closeable or use try-with-resources (available since Java 7) to make sure the resource(s) is(are) always closed.

Related

Setting connection reference to null after closing it

Is it required/good practice to set the connection reference to null after closing it?
I am closing connections in finally block.
conn.close();
conn = null;
I am facing connection wait timeout exception during performance testing
as the maximum connections are getting exceeded.
You'll see this pattern in use when people want to explicitly throw away a reference, and thus aid garbage collection, and trigger finalisers. This is virtually always redundant.
If the conn variable is used to indicate that a new connection is required (by making it a field, perhaps, and resetting it to null before later reference) then that's a different pattern, but unrelated to immediate resource management.

Jdbc Connection Refrences set to null

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();
}

Best approach for returning connection objects to HikariCP pool

I am trying to use HikariCP connection pool. I was able to get it to work and get a connection that I could use. I am not sure what is the best approach for returning the connection to the pool.
I have the following questions:
Should I close the connection when I am done, rely on idleTimeout
and maxLifetime settings or is there another call that I can use so
as not to hog the connections from the pool?
If I close the connections (instead of returning to the pool), would
that not result in additional connection objects being created
to meet the requirements of the connection pool size?
Looking for helpful suggestions.
As with most connection pools, Hikari doesn't give you an actual JDBC Connection when you ask for one. What it does instead is give you a proxy that implements the Connection interface. In the case of Hikari - it's a ConnectionProxy object.
This proxy serves a few purposes, the main of which is - take the control of opening/closing connections and statements away from you and into the connection pool. This happens automagically and you should be using your connections as usual. This includes closing them after use.
If you look at the source code for Hikari, at the ConnectionProxy class in particular, you will see that the close() method is very different from the standard one. The code reads as:
Mark the connection as closed, do cleanup, reset underlying connection state and params.
Hence, simply calling close() will just clean and return the connection to the pool.

Is a PreparedStatement left "open" if the reference is overwritten?

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.

How many times should I close the connection In SQL?

I have lots of method in my database class that all of them have one statement, when should I close the connection? In each method or at the end of database class?
You should close the connection when you are finished your transaction. Since we don't know the contents of the class or its usage, it's impossible to tell when your access of the connection begins or ends.
Actually, that may not even be true if the connection is dedicated for a specific usage and not in a pool. You may want to keep it open for the duration of your application.
We've found that the best policy is to get a connection from the connection pool, execute a single transaction, and then put the connection back into the pool immediately. This way you don't have a connection being held onto for long blocks of logic, thus preventing other threads from using it - which is an issue for scalability.
As a best practice, you should close the connection in the logical place after you are done - right after all of database activity for that task is done.
Generally, you should close a connection in the same method that opens it. Closing and opening connections isn't an arduous task, since modern DB servers keep even closed connections on "hot standby", so they are quickly accessed through a connection pool. Leaving them open though...that can get you in trouble and can be a nightmare to debug.
use lombok and it will handle both try/catch and conn.close() for you
public void doSomething() throws SQLException {
#Cleanup Connection connection = database.getConnection();
}
lombok
It depends when and how repeatedly you are using these methods. If they are sequential you should close the connection only in the end, instead of open and close often
This largely depends on what your Database class does. If your methods are called individually at various times then the methods should be responsible for opening and closing the connection. However, if the class does some kind of big processing operation that calls many methods then you may want to open and close the connection outside of the individual methods.
The most important thing is that wherever you open the connection, you also close the connection. Otherwise you get into the business of making assumptions about the state of the connection which can get you into trouble.
Close the connection (and statement and resultset!) in the same method block as you've acquired it, in the finally block of the try block where they are opened.
The general idiom is:
public void doSomething() throws SQLException {
Connection connection = null;
try {
connection = database.getConnection();
} finally {
if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
}
}
Closing of connection, statement and resultset should happen in reversed order as they're opened.
If your actual concern is performance, then consider using a connection pool to improve connecting performance, for example C3P0. This by the way does not change the general idiom. Just continue writing the same idiom, the connection pooling implementation will worry itself further under the hoods.
Also see this article for more practices/examples.
Always close the connection when you finish executing your transaction. It is a good practice to obtain and close your connection in the same method. If you have separate transactions that are tightly coupled you might execute them with the same connection, but for best practices, I try to execute one transaction per connection.
If it is an option, don't explicitly mess with connections at all. Use a full blown orm framework like hibernate or use something significantly more lightweight like spring jdbc templates.
It depends somewhat on the context your application operates in. If it's a web app you need to be careful to open your connection, do whatever work is needed, and close the connection quickly. However, in a C/S or batch environment it may be better to acquire the connection and hold onto it as long as the user is interacting "frequently" (for whatever value of "frequently" you choose), especially if the user has expectations of rapid response time and it's expensive (in terms of time or resources) to acquire the connection to your particular variety of database.
I like to set a timer every time the user has the app go to the database. If/when the timer expires, close the connection, then re-open the next time he/she/it wants to hit the database again. Timer expiration can be somewhere between 1 and 20 minutes. Just so long as it's less than the database's "inactivity disconnect" time.
Share and enjoy.

Categories

Resources