jdbc why isn't javax.sql.PooledConnection inherited from java.sql.Connection - java

Every time we implement a PooledConnection we write
class MyConnection implements PooledConnection, Connection {
// implement methods of PooledConnection and Connection
}
And I am wondering why PooledConnection was not designed as extends Connection? since a PooledConnection is always a Connection after all.

I'm by no means sure, but I imagine the reason PooledConnection doesn't extend Connection is so that you can make a significantly simpler PooledConnection implementation that uses any other existing Connection implementation, allowing code-reuse and keeping functionality separate.

... since a PooledConnection is always a Connection after all.
Actually, that's the whole point. The PooledConnection interface design allows the PooledConnection instance to be a distinct object from the Connection instance.
Why would you do that? Well in an XA implementation, there are potentially many different implementations of Connection from different database vendors, and the PooledConnection classes are designed to deal with "stuff" over the top of that; e.g. coordination of transactions across multiple databases. Keeping the two interfaces distinct means that the XA implementation doesn't need to implement XA-level connections as wrapper objects.
And of course, since PooledConnection and Connection interfaces, they can be implemented by the same connection class ... if the situation requires it.
(Or at least, that is my theory. To get a definitive answer, you'd need to ask the people who wrote the specification(s) that gave rise to those interfaces.)

A PooledConnection is a handle to a physical connection. This physical connection object might be a a JDBC Connection, but on the other hand it could just as well be a lower-level database-specific construct.
The handle is what a connection pool uses to create logical Connection-objects to hand out to clients of the connection pool (using the getConnection() method. When the client closes that connection, the connection pool is notified that the PooledConnection is available again.
A PooledConnection is not intended to be used directly as a Connection, so it does not extend the Connection interface.

Related

How to reset a JDBC Connection object?

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

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.

Why database connection object or connection pool needs to be made singleton?

I have gone through couple of articles on singleton example. And I could see that developers sometimes make the database connection object or connection manager as singleton implementation. In some of the posts even it was advised to use Database connection pool.
Well Singleton means to create a single instance, so basically we restrict the access. e.g. Printer or hardware access, logger access in which we try to restrict the access of the user to one at a time using singleton. However what is the purpose of using singleton in DB connection objects?
If I can understand correctly creating a Database connection as singleton means that app server will have only one instance. Does this mean only one user can access the Database connection and next user has to wait until the connection is closed?
Please advise.
I think you understand correctly the implication of making the connection itself a singleton. Generally it is not a good idea (although in some very particular case it could make sense).
Making a connection manager or a connection pool a singleton is completely different. The pool itself would handle a collection of connections and it can create new as they are needed (up to a limit) or re-use the ones that have been already used and discarded.
Having several connection pools at the same time would lose the advantages of the pool:
It would be harder to control the total number of connections open
One pool could be creating connections while other could have connections available
Hope this helps to clarify the subject. You might want to read more on connection pools.
Q: "However what is the purpose of using singleton in DB connection objects?" A: There is (almost always) none. So your thinking is correct.
Q: "Does this mean only one user can access the Database connection and next user has to wait until the connection is closed?"
A: Depends (to first part) and No (to second part after "and"). In single-threaded application only one user will use the database at one time and another will wait, until dispatch of first user ends but not when the connection is closed. Once connection is closed, you need to create another connection to make use of database. In multi-threaded application many threads may be using the same connection instance and result really depends on the vendor implementation: may block dispatching (effectively transforming your app to single-threaded app) or throw exceptions or even something different. However, such design in multi-threaded app is in my opinion a programmer-error.

should a db connection be a singleton?

What is the best way in Java to create a singleton?
Should a DB connection be a singleton (being a singleton it's automatically thread-safe)? Because theoretical the DB can't be accessed by many users in the same time.
A DB connection should not normally be a Singleton.
Two reasons:
many DB drivers are not thread safe. Using a singleton means that if you have many threads, they will all share the same connection. The singleton pattern does not give you thread saftey. It merely allows many threads to easily share a "global" instance.
Personally, I think Singleton often leads to bad design: See this post (by somebody else) http://tech.puredanger.com/2007/07/03/pattern-hate-singleton/
Instead of doing this consider a database pool. The pool is shared (and could be a singleton if you wanted). When you need to do database work your code does this:
getConnectioFromPool();
doWork()
closeConnection() // releases back to pool
Sample Pool Libraries:
http://commons.apache.org/dbcp/
http://jolbox.com/
The best way to create a singleton (as of today) is the enum singleton pattern (Java enum singleton)
I doubt, that a Singleton is necessary or of any value for a database connection. You probably want some lazy creation: a connection is created upon first demand and cached, further requests will be fullfilled with the cached instance:
public ConnectionProvider {
private Connection conn;
public static Connection getConnection() {
if (conn == null || conn.isClosed()) {
conn = magicallyCreateNewConnection();
}
return conn;
}
}
(not thread safe - synchronize, if needed)
What is the best way in Java to create
a singleton?
Follow the design pattern creation guidelines. i.e private constructor, etc.
Should a DB connection be a singleton
(being a singleton it's automatically
thread-safe)?
creating a DB connection as a singleton might be a poor design choice in many scenarios. Use it only if you are sure that you don't need DB concurrency. If you have multiple users logged in at the same time, or even if your single user spawns many threads that need to access the DB, then a DB Connection pool is a better choice. You can use either apache or tomcat db connection pools. THese classes are defined for example in the package
org.apache.commons.dbcp.*;
org.apache.tomcat.dbcp.dbcp.*;
where dbcp stands for database connection pooling.
The biggest reason for using a connection pool is that on average the time it takes for the DB access (DML etc) is much smaller than the time it takes to create a connection and then close the connection. Additionally, don't forget to close your ResultSet, PreparedStatement and Connection variables after the transaction is done.
Because theoretical the DB can't be
accessed by many users in the same
time.
Why not? DB in most cases is meant to be used concurrently. You have these DB isolation levels - READ_COMMITTED, READ_UNCOMMITTED, SERIALIZED etc.
SERIALIZED is the case where your DB becomes single user access.
Singletons are a pattern - there's no explicit way to create one, you just follow the design practice.
So, if you're using a database that can handle concurrent reads/writes (i.e. MySQL), you don't need to worry so much about thread safety. If you're using a DB that's doesn't do concurrent writes well (SQLite), then a singleton should theoretically work.

connection pool for proprietary connection api (non jdbc)

I am using an API to connect to some hardware terminals and networks. The API allows me to connect to the servers, disconnect and interrogate for data, pretty similar to what JDBC connection allows you to do. Anyway, since this is not using the JDBC Connection interface, I cannot use a connection pooling already existing.
I would like to avoid writing one myself if I can use one already existing, or maybe just build a small adapter on top of that. Anyone knows of any framework/library that would allow me to enable connection pooling, that can handle my connections, can ensure that the connection is alive all the time etc?
I have looked at Commons Pool, but that only gives you a few classes to put/get your connections ... it doesn't do any of the maintenance tasks etc (check if connection is invalid from time to time, reconnect etc). I can add on top of that the mechanism of connection checking and reconnecting if any issues etc in case there is nothing out there that does this already.
Cheers, Stef.
Apache Commons Pool actually supports creating, destroying and checking objects for validity before handing them out with the PoolableObjectFactory class, which you use with the actual pool implementation by passing it as a parameter:
final PoolableObjectFactory objectFactory = new MyPoolableObjectFactoryImpl();
final ObjectPool pool = new GenericObjectPool(objectFactory);
You can look into dbcp http://commons.apache.org/dbcp/
it's BasicDataSource provide methods such as maxActive, maxIdle, maxWait etc check documentation for more
http://commons.apache.org/dbcp/apidocs/org/apache/commons/dbcp/BasicDataSource.html
interesting one if you are going for new implementation try tomcat 7 jdbc connection pool
http://people.apache.org/~fhanik/jdbc-pool/jdbc-pool.html
[edit] useless for the scenario -hGx so upvoting Henning's post

Categories

Resources