How to reset a JDBC Connection object (that is, a java.sql.Connection object)?
I have explored the concept of connection pooling. When a connection pool is used, a Connection object can be recycled. But how can a connection pool recycle a Connection object? I think that a connection needs to be "reset" (for example, if it is in a transaction, then perhaps rollback it, but there may be more things to reset) before it can be reused. But I cannot find such a "reset" method in the Java documentation about the class java.sql.Connection.
If you are talking about what you as a user of a connection should do, then that is simple: call close() on the connection. Closing the logical connection will signal to the connection pool that the connection is available for reuse, and the connection pooling manager is then responsible for performing the necessary reset, invalidation of statement handles, etc.
If you are talking about what you as the implementer of a connection pooling manager should do, that is where things become complicated.
Historically, JDBC provides no way to 'reset' a java.sql.Connection, other than by your own code (or your third-party connection pool) remembering the initial configuration, and restoring it after use, and keeping track of objects like statements and result sets and closing them when the connection is returned to the pool.
Originally, the intended way to reset connections in JDBC was for an application server to use a driver's javax.sql.ConnectionPoolDataSource as a factory for javax.sql.PooledConnection objects. These PooledConnection objects serve as handles for physical connections to be held in a connection pool (to be clear, ConnectionPoolDataSource is not a connection pool, it is a data source for a connection pool). The application server would then expose a javax.sql.DataSource handing out logical Connection objects, where on Connection.close(), the driver specific implementation of PooledConnection would take care of any necessary reset of a connection (though JDBC underspecifies what is 'necessary').
However, in practice this route is hardly ever used because support in drivers was (and often still is) spotty, inconsistent or downright incorrect, and JDBC wasn't clear enough on exactly what needed to be done when the logical connection was closed. The world has also shifted to using third-party connection pool libraries that do not use ConnectionPoolDataSource.
JDBC 4.3 (Java 9 and higher) introduced the methods Connection.beginRequest() and Connection.endRequest() to be called by connection pooling managers, which would seem to fit such pattern, but unfortunately JDBC 4.3 doesn't actually specify what kind of things an implementation should or should not do in response to beginRequest and endRequest.
In short, there is no real general way to reset a connection in JDBC.
Do you try to close() method and reinitialize Connection object again.
close()
Releases this Connection object's database and JDBC resources immediately instead of waiting for them to be automatically released
Related
I am really getting confused between these 2 now as below :
1. is the returning of only a Singleton instance to a db connection during the entire run time of a JAVA app
2. is the concept of Thread pool connections in general... I mean if we are planning to have only a singleton instance to a db connection obj, why even have a concept of pools, though i do get what exactly a pool is used for
Are these 2 not very opposite concepts, or am i mixing up anything here...?
is the returning of only a Singleton instance to a db connection during the entire run time of a JAVA app?
you may not want to return a Singleton object for a database connection. You can choose to do if database concurrency not required. In a multi threaded environment best option is to go for Connection pool.
is the concept of Thread pool connections in general..
Establishing a database connection is a very resource-intensive process and involves a lot of overhead. Moreover, in a multi-threaded environment, opening and closing a connection can worsen the situation greatly.
Creating JNDI in server and use it in your web app.
Context context=new InitialContext();
DataSource dataSource=(DataSource)
context.lookup("jdbc/test_jndi");
so when DataSource uses connection pooling, the lookup return a connection from the pool of available connection objects. If there is no available connection, the lookup creates a new connection.
Connection connection=dataSource.getConnection
("testuser","testpwd");
// ...
connection.close();
Once the application is done with database processing, it explicitly closes the connection. This makes the connection available again for reuse again. The closing event of the pooled connection signals the pooling module to restore back to the connection pool.
Any resource shared requires overhead of handling concurrent access so you want to reduce that by not having singletons always. Moreover to reduce resource-intensive process connection pooling is preferred.
I have a severe problem with my database connection in my web application. Since I use a single database connection for the whole application from singleton Database class, if i try concurrent db operations (two users) the database rollsback the transactions.
This is my static method used:
All threads/servlets call static Database.doSomething(...) methods, which in turn call the the below method.
private static /* synchronized*/ Connection getConnection(final boolean autoCommit) throws SQLException {
if (con == null) {
con = new MyRegistrationBean().getConnection();
}
con.setAutoCommit(true); //TODO
return con;
}
What's the recommended way to manage this db connection/s I have, so that I don't incurr in the same problem.
Keeping a Connection open forever is a very bad idea. It doesn't have an endless lifetime, your application may crash whenever the DB times out the connection and closes it. Best practice is to acquire and close Connection, Statement and ResultSet in the shortest possible scope to avoid resource leaks and potential application crashes caused by the leaks and timeouts.
Since connecting the DB is an expensive task, you should consider using a connection pool to improve connecting performance. A decent applicationserver/servletcontainer usually already provides a connection pool feature in flavor of a JNDI DataSource. Consult its documentation for details how to create it. In case of for example Tomcat you can find it here.
Even when using a connection pool, you still have to write proper JDBC code: acquire and close all the resources in the shortest possible scope. The connection pool will on its turn worry about actually closing the connection or just releasing it back to pool for further reuse.
You may get some more insights out of this article how to do the JDBC basics the proper way. As a completely different alternative, learn EJB and JPA. It will abstract away all the JDBC boilerplate for you into oneliners.
Hope this helps.
See also:
Is it safe to use a static java.sql.Connection instance in a multithreaded system?
Am I Using JDBC Connection Pooling?
How should I connect to JDBC database / datasource in a servlet based application?
When is it necessary or convenient to use Spring or EJB3 or all of them together?
I've not much experience with PostgreSql, but all the web applications I've worked on have used a single connection per set of actions on a page, closing it and disposing it when finished.
This allows the server to pool connections and stops problems such as the one that you are experiencing.
Singleton should be the JNDI pool connection itself; Database class with getConnection(), query methods et al should NOT be singleton, but can be static if you prefer.
In this way the pool exists indefinitely, available to all users, while query blocks use dataSource.getConnection() to draw a connection from the pool; exec the query, and then close statement, result set, and connection (to return it to the pool).
Also, JNDI lookup is quite expensive, so it makes sense to use a singleton in this case.
I am facing some use related to GET_LOCK in MySQL. I am using c3p0 connection provider. Does getConnection() method in c3P0 create new connection every time or reuse the connection?
getConnection on DataSource gets the connection from connection pool. If there isn't any available and maxPoolSize isn't reached then it opens new connection. If the maxPoolSize is reached then it waits for some connection to return to the pool. (it must be released by the thread which is using it)
After the thread releases the connection then it is returned to the pool and might be reused by some other thread.
The documentation is http://www.mchange.com/projects/c3p0/
c3p0 maintains a pool of Connections, which are reused for multiple clients.
however, you cannot make any assumption that a Connection you use will be the same Connection you will see again. you might receive any Connection from c3p0's pool, there's no guarantee or likelihood you'll see one you've already seen. and, depending on your configuration, c3p0 tests, expires, and replaces Connections behind the scenes.
if you are trying to associate a lock with a Connection in one client session and then release it in another, well, that won't work and will break things fast. really, with any explicit locking, your acquisition and release should be done in one client session, using try / finally semantics to ensure lock release.
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.
Example code in "http://tomcat.apache.org/tomcat-7.0-doc/jdbc-pool.html" explicitly closes a connection after it is used.
However according to my understanding, should not it be the connection pool's responsibility to manage active and idle connections?
Why would not I want a connection to be re-used by another transaction?
You must close the connection so that you can release it back to the pool. The "Connection" you get from the pool does not, per se, represent the actual, physical connection to the DB. Rather it's a wrapper. So, closing the connection informs the pool that it is free for use by other clients of the pool.
You need to call Connection.close() to return the connection to the pool, it doesnt actually close the underlying connection.