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();
}
Related
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.
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.
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.
I not very good in java.
I have made a website for a client but am continuously getting an error like Server connection failure during transaction. Due to underlying exception: 'com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: User root already has more than 'max_user_connections' active connections'.
The website hosting that I am using provides only 10 max_user_connections. But if I continuously use that site, I get this error because of continuously hits on the webserver.
What can be the reason behind this?
Am I not closing the connections right?
I have closed all the connections using con.close().
Please help
Regards Apurv
To open the connection I have used
Connection con=null;
Statement st=null;
Class.forName("com.mysql.jdbc.Driver").newInstance();
String useq="root";
String paq="manager";
String url="jdbc:mysql://localhost:3306/jayna?autoReconnect=true";
con=DriverManager.getConnection(url,useq,paq);
st=con.createStatement();
To close the connection I have used
if(rs!=null){
rs.close();
}
if(st!=null){
st.close();
}
if(con!=null){
con.close();
}
I haven't used a database pool but what can be the use of that when I am closing each of the connection properly??
This seems like a case of connection leak.
Are you sure, you have closed all the connections?
Conneciton.close() throws IOException. Check if it is successfully able to close connections.
Use netstat or other tools to find whether connections are really closed or are in WAITING state or something.
I think you should increase number of connections. Because if there are 10 slow query and you get 11 requests to your site 11 request couldn't be processed and you get this error.
So:
Try increase a number of connections.
Try to find slow queries(using slow query log) and optimize them
Connection pooling is a technique to provide a set of ready-to-use connections, one of the advantages being that you save the creation/opening time on each call. Another advantage is that the connection pooler can help detect abandoned connections, ie connections that the application forgot to close.
There's a standard connection pool in Tomcat, for 5.x version Tomcats look here for some info, for version 6 look here and for version 7 info can be found here. Its removeAbandoned and logabandoned features can help you determine whether your app really forgets to close connections, or 10 just isn't enough - see Andrej's suggestion, you should profile your queries.
As others have said, you either are not getting connections closed or your application simply needs more than 10 concurrent connections under some load conditions.
If the error always occurs on the 11th request, it's likely you're never getting the connections closed.
If it occurs sometime later, unpredictably, and goes away on its own, it's more likely 10 simply isn't sufficient for certain load scenarios.
If it occurs later, unpredictably, but never goes away on its own, it's possible you're failing to close connections only in specific cases that aren't hit every time.
If 10 is too small for some load scenarios (option 2), you should both check your queries and code logic to ensure you're not holding connections way longer than necessary and you should probably try to move to a Connection Pool, as others have suggested. Among other things, creating new Connections from scratch has more overhead than reusing them from a pool, so that could be causing individual accesses to take much longer than necessary.
This problem can be solved by using a Singleton class structure for initializing connection objects.
Using the Singleton pattern, whenever a connection object is initialized, rather than creating a new object, it will look for existing instance of connection object and use that one, if it exists.
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.