Reset JDBC connections of Connection Pool in Java - java

Scenario:
There is something called FAN notification in Oracle Database, which is used for High Availability.
Whenever I will get this notification in my Java application I want to reset all the JDBC connections object available in my Connection Pool.
But the problem is, even if I reset the connection pool objects, there will be some JDBC transaction going on using old connection objects.
My question is, can we somehow change that (which is in use) connection object with the new object and copy or transfer the transactions to new connection object without any inflight transaction.
[update]: This scenario is handled between server and database using something called Grid Link. But I want to handle it in application end, by removing all the JDBC connection objects from connection pool, these connection objects will point to new database instance which is up and running.
If it is not possible please suggest me some alternative solution.

Related

How to close com.microsoft.sqlserver.jdbc.SQLServerDataSource

I'm using sql server jdbc driver mssql-jdbc-9.2.1.jre8-sources.jar and create an object of com.microsoft.sqlserver.jdbc.SQLServerDataSource.
After setting it up with host-credential-etc, opening Connection and closing Connection, how do I close SQLServerDataSource object itself, I could not find any method in API.
https://javadoc.io/doc/com.microsoft.sqlserver/mssql-jdbc/9.2.1.jre8/com/microsoft/sqlserver/jdbc/SQLServerDataSource.html
Note to closer: I'm NOT using C3P0 connection pool, that may have close option.
The SQLServerDataSource is a simple data source that does not provide any form of connection pooling, it only serves as a factory of physical, non-pooled JDBC connections. As such, you do not need to close, destroy or otherwise dispose of this class (other than normal garbage collection).
The need to close a data source only exists for data sources that are backed by a connection pool (like c3p0), to release those pooled connections and maybe end house-keeping threads.

Should I have a single database connection or one connection per task? [duplicate]

This question already has answers here:
How to manage db connections on server?
(3 answers)
Closed 7 years ago.
I have a Java server and PostgreSQL database.
There is a background process that queries (inserts some rows) the database 2..3 times per second. And there is a servlet that queries the database once per request (also inserts a row).
I am wondering should I have separate Connection instances for them or share a single Connection instance between them?
Also does this even matter? Or is PostgreSQL JDBC driver internally just sending all requests to a unified pool anyway?
One more thing should I make a new Connection instance for every servlet request thread? Or share a Connection instance for every servlet thread and keep it open the entire up time?
By separate I mean every threads create their own Connection instances like this:
Connection connection = DriverManager.getConnection(url, user, pw);
If you use a single connection and share it, only one thread at a time can use it and the others will block, which will severely limit how much your application can get done. Using a connection pool means that the threads can have their own database connections and can make concurrent calls to the database server.
See the postgres documentation, "Chapter 10. Using the Driver in a Multithreaded or a Servlet Environment":
A problem with many JDBC drivers is that only one thread can use a
Connection at any one time --- otherwise a thread could send a query
while another one is receiving results, and this could cause severe
confusion.
The PostgreSQLâ„¢ JDBC driver is thread safe. Consequently, if your
application uses multiple threads then you do not have to worry about
complex algorithms to ensure that only one thread uses the database at
a time.
If a thread attempts to use the connection while another one is using
it, it will wait until the other thread has finished its current
operation. If the operation is a regular SQL statement, then the
operation consists of sending the statement and retrieving any
ResultSet (in full). If it is a fast-path call (e.g., reading a block
from a large object) then it consists of sending and retrieving the
respective data.
This is fine for applications and applets but can cause a performance
problem with servlets. If you have several threads performing queries
then each but one will pause. To solve this, you are advised to create
a pool of connections. When ever a thread needs to use the database,
it asks a manager class for a Connection object. The manager hands a
free connection to the thread and marks it as busy. If a free
connection is not available, it opens one. Once the thread has
finished using the connection, it returns it to the manager which can
then either close it or add it to the pool. The manager would also
check that the connection is still alive and remove it from the pool
if it is dead. The down side of a connection pool is that it increases
the load on the server because a new session is created for each
Connection object. It is up to you and your applications'
requirements.
As per my understanding,You should defer this task to the container to manage connection pooling for you.
As you're using Servlets,which will be running in a Servlet container, and all major Servlet containers that I'm aware of provide connection pool management.
See Also
Best way to manage database connection for a Java servlet

Saving conexion in Java EE's Session .vs. a connection pool

I know that Java EE's session object can store complex objects, like a connection to a database.
I'm pondering how to implement a certain application for a programming practice, made with Java EE. My first option to use a connection pool, which is very easy with Java EE.
I'm wondering, out of curiosity, and also to properly justify the decision, what are the pros and cons of creating a connection to the database any time a client starts a session and storing it there, against the use of a connection pool.
Thanks a lot.
A resource pool will optimise the handling of the resource (your database connection) in a way your system can cope with it. Even though you can end up out of resources if you have a lot of opened connections.
That is more likely to happen if you store your database connection in the session context. Web applications don't need to be connected all the time to a database, that connection can be stablished at the beginning of a new operation and closed at the end. Using a resource pool you return your connection back to the pool when you no longer need it, so a new user (session in the web paradigm) can use that resource you have already released instead of creating a new one.
The pool will also handle the scenario in which some resources have been idle for a long time (no one has used them in a specific amount of time) and then it will release those resources.
When storing a database connection in the session you are never releasing the resource but keeping a permanent reference to it that will last as long as the user session does. You may not face any issues in a short time with that, specially if there are really few users connected at the same time. But in real world applications you will definitively find them.
Thus, storing a database connection in the session context is considered as a bad practice.
EDIT: I forgot to mention that should only store Serializable objects in the session so, if the application server decides to passivate a session, it can be persisted and restored when the application server decides to reactivate it. A database connection is not a Serializable resource.
Using a connection pool allows you maximize the usability of your connections. This means less connections = less memory = less sockets etc. The reason a pool is better than saving in a session is what happens if someone drops out unexpectedly? If you have a connection in your session, you risk keeping that connection alive for a long time, possibly indefinitely.

JDBC Connection Pooling: Connection Reuse?

As per my understanding, JDBC Connection Pooling (at a basic level) works this way:
create connections during app initialization and put in a cache
provide these cached connections on demand to the app
a separate thread maintains the Connection Pool, performing activities like:
discard connections that have been used (closed)
create new connections and add to the cache to maintain a specific count of connections
But, whenever I hear the term "connection reuse" in a JDBC Connection Pooling discussion, I get confused. When does the connection reuse occurs?
Does it means that Connection Pool provides the same connection for two different database interactions (without closing it)? Or, is there a way to continue using a connection even after it gets closed after a DB call?
Connection pooling works by re-using connections. Applications "borrow" a connection from the pool, then "return" it when finished. The connection is then handed out again to another part of the application, or even a different application.
This is perfectly safe as long as the same connection is not is use by two threads at the same time.
The key point with connection pooling is to avoid creating new connections where possible, since it's usually an expensive operation. Reusing connections is critical for performance.
The connection pool does not provide you with the actual Connection instance from the driver, but returns a wrapper. When you call 'close()' on a Connection instance from the pool, it will not close the driver's Connection, but instead just return the open connection to the pool so that it can be re-used (see skaffman's answer).
Connection pooling reuses connections.
Here is how apache dbcp works underline.
Connection poolableConnection= apacheDbcpDataSource.getConnection();
Apache DBCP implementation returns connection wrapper which is of type PoolableConnection.
poolableConnection.close();
PoolableConnection.close() inspects if actual underlying connection is closed or not, if not then it returns this PoolableConnection instance into connection pool (GenericObjectPool in this case).
if (!isUnderlyingConectionClosed) {
// Normal close: underlying connection is still open, so we
// simply need to return this proxy to the pool
try {
genericObjectPool.returnObject(this); //this is PoolableConnection instance in this case
....
}
My understanding is the same as stated above and, thanks to a bug, I have evidence that it's correct. In the application I work with there was a bug, an SQL command with an invalid column name. On execution an exception is thrown. If the connection is closed then the next time a connection is gotten and used, with correct SQL this time, an exception is thrown again and the error message is the same as the first time though the incorrect column name doesn't even appear in the second SQL. So the connection is obviously being reused. If the connection is not closed after the first exception is thrown (because of the bad column name) then the next time a connection is used everything works just fine. Presumably this is because the first connection hasn't been returned to the pool for reuse. (This bug is occurring with Jave 1.6_30 and a connection to a MySQL database.)

What is a Connection in JDBC?

What is a Connection Object in JDBC ? How is this Connection maintained(I mean is it a Network connection) ? Are they TCP/IP Connections ? Why is it a costly operation to create a Connection every time ? Why do these connections become stale after sometime and I need to refresh the Pool ? Why can't I use one connection to execute multiple queries ?
These connections are TCP/IP connections. To not have to overhead of creating every time a new connection there are connection pools that expand and shrink dynamically. You can use one connection for multiple queries. I think you mean that you release it to the pool. If you do that you might get back the same connection from the pool. In this case it just doesn't matter if you do one or multiple queries
The cost of a connection is to connect which takes some time. ANd the database prepares some stuff like sessions, etc for every connection. That would have to be done every time. Connections become stale through multiple reasons. The most prominent is a firewall in between. Connection problems could lead to connection resetting or there could be simple timeouts
To add to the other answers:
Yes, you can reuse the same connection for multiple queries. This is even advisable, as creating a new connection is quite expensive.
You can even execute multiple queries concurrently. You just have to use a new java.sql.Statement/PreparedStatement instance for every query. Statements are what JDBC uses to keep track of ongoing queries, so each parallel query needs its own Statement. You can and should reuse Statements for consecutive queries, though.
The answers to your questions is that they are implementation defined. A JDBC connection is an interface that exposes methods. What happens behind the scenes can be anything that delivers the interface. For example, consider the Oracle internal JDBC driver, used for supporting java stored procedures. Simultaneous queries are not only possible on that, they are more or less inevitable, since each request for a new connection returns the one and only connection object. I don't know for sure whether it uses TCP/IP internally but I doubt it.
So you should not assume implementation details, without being clear about precisely which JDBC implementation you are using.
since I cannot comment yet, wil post answer just to comment on Vinegar's answer, situation with setAutoCommit() returning to default state upon returning connection to pool is not mandatory behaviour and should not be taken for granted, also as closing of statements and resultsets; you can read that it should be closed, but if you do not close them, they will be automatically closed with closing of connection. Don't take it for granted, since it will take up on your resources on some versions of jdbc drivers.
We had serious problem on DB2 database on AS400, guys needing transactional isolation were calling connection.setAutoCommit(false) and after finishing job they returned such connection to pool (JNDI) without connection.setAutoCommit(old_state), so when another thread got this connection from pool, inserts and updates have not commited, and nobody could figure out why for a long time...

Categories