jConnect4 pooled connection does not work as documented - jdbc

Official Sybase jConnect Programmers Reference suggests following way to use pooled connections:
SybConnectionPoolDataSource connectionPoolDataSource = new SybConnectionPoolDataSource();
...
Connection ds = connectionPoolDataSource.getConnection();
...
ds.close();
However getDataSource always causes exception. I decompiled SybConnectionPoolDataSource and found that the method call explicitly generates an error:
public Connection getConnection() throws SQLException
{
ErrorMessage.raiseError("JZ0S3", "getConnection()");
return null;
}
Does anyone have an idea why the documentation contradicts to the implementation?

I can't comment specifically for Sybase because 1) I don't use it and 2) your link doesn't work, but I can try to give you a theory based on my own experience maintaining a JDBC driver (Jaybird/Firebird JDBC) and looking at what some of the other implementations do.
The ConnectionPoolDataSource is probably the least understood part of the JDBC API. Contrary to what the naming suggests and how it has been implemented in some JDBC implementations this interface SHOULD NOT provide connection pooling and should not implement DataSource (or at least: doing that can lead to confusion and bugs; my own experience).
The javadoc of the ConnectionPoolDataSource is not very helpful, the javax.sql package documentation provides a little bit more info, but you really need to look at the JDBC 4.1 specification, Chapter 11 Connection Pooling to get a good idea how it should work:
[...] the JDBC driver provides an implementation of ConnectionPoolDataSource that the application server uses to build and manage the connection pool.
In other words: ConnectionPoolDataSource isn't meant for direct use by a developer, but instead is used by an application server for its connection pool; it isn't a connection pool itself.
The application server provides its clients with an implementation of the DataSource interface that makes connection pooling transparent to the client.
So the connection pool is made available to the user by means of a normal DataSource implementation. The user uses this as would it be one that doesn't provide pooling, and uses the connections obtained as if it is a normal physical connection instead of one obtained from a connection pool:
When an application is finished using a connection, it closes the logical connection using the method Connection.close. This closes the logical connection but does not close the physical connection. Instead, the physical connection is returned to the pool so that it can be reused.
Connection pooling is completely transparent to the client: A client obtains a pooled connection and uses it just the same way it obtains and uses a non pooled connection.
This is further supported by the documentation of PooledConnection (the object created by a ConnectionPoolDataSource):
An application programmer does not use the PooledConnection interface directly; rather, it is used by a middle tier infrastructure that manages the pooling of connections.
When an application calls the method DataSource.getConnection, it gets back a Connection object. If connection pooling is being done, that Connection object is actually a handle to a PooledConnection object, which is a physical connection.
The connection pool manager, typically the application server, maintains a pool of PooledConnection objects. If there is a PooledConnection object available in the pool, the connection pool manager returns a Connection object that is a handle to that physical connection. If no PooledConnection object is available, the connection pool manager calls the ConnectionPoolDataSource method getPoolConnection to create a new physical connection. The JDBC driver implementing ConnectionPoolDataSource creates a new PooledConnection object and returns a handle to it.
Unfortunately, some of JDBC drivers have created data sources that provide connection pooling by implementing both DataSource and ConnectionPoolDataSource in a single class, instead of the intent of the JDBC spec of having a DataSource that uses a ConnectionPoolDataSource. This has resulted in implementations that would work if used as a normal DataSource, but would break if used as a ConnectionPoolDataSource (eg in the connection pool of an application server), or where the interface was misunderstood and the wrong methods where used to create connections (eg calling getPooledConnection().getConnection()).
I have seen implementations (including in Jaybird) where the getPooledConnection() would be used to access a connection pool internal to the implementation, or where only connections obtained from the getConnection() of the implementation would work correctly, leading to all kinds of oddities and incorrect behavior when that implementation was used to fill a connection pool in an application server using the getPooledConnection().
Maybe Sybase did something similar, and then decided that wasn't such a good idea so they changed the DataSource.getConnection() to throw an exception to make sure it wasn't used in this way, but at the same time maintaining the API compatibility by not removing the methods defined by DataSource. Or maybe they extended a normal DataSource to easily create the physical connection (instead of wrapping a normal one), but don't want users to use it as a DataSource.

Related

Closing connections in Spring DATA jpa

I am using spring data jpa and hikari connection pooling. In repository file, I am using methods to connect to database. I would like to know how and where to close the database connections.
Repository
public interface abc extends JPARepository<abc, int>{
List<abc> findById(int id);}
Any help on how to close the connections and where(service layer or repository) would be really appreciated
`
With Connection Pooling, using the framework, The task of creating a connection before each operation and closing the connection after the operation is now taken from the programmer and transferred to the Spring Context:-
The application requests a connection from the connection pool.
If an unused connection exists, it is returned by the pool; otherwise, the pool creates a new connection.
The application sends a query to the Hybrid Data Pipeline connectivity service.
The application obtains query results.
The application displays the result to the end-user.
The application closes the connection, which returns the connection to the pool.
Note: The application calls the close() method, which allows the connection to remain open. The pool receives the notification of the close request.

Does Spring JDBC supports XA connection pools (for example, Oracle UCP)?

I'd like to add XA connection pool to my Spring based application, specifically Oracle UCP. This pool works on XADataSource and XAConnection objects. Standard DataSource.getConnection(...) methods are not supported.
Trying working with that pool (that I am able to successfully set up in Spring) I am getting an error related to the fact that getConnection(...) methods invoked by JdbcTemplate are disabled and should not be used. I am just wondering whether any of Spring JDBC classes are able to work with XADataSource and XAConnections? Probably there are another ways to use Spring with XA connection pools? Will appreciate any advices on that topic.
Just for those who may experience similar problems - Spring doesn't support directly XA connection pools (through native XADataSource.getXAConnection(...) methods). You need to write a kind of wrapper utilizing DatSource.getConnection(...) methods.

How to safely and efficiently connect to a MongoDB replicaset instance with the C# Driver

I am using MongoDB with the C# driver and am wondering what is the most efficient yet safe way to create connections to the database.
Thread Safety
According to the Mongo DB C# driver documentation the MongoClient, MongoServer, MongoDatabase, MongoCollection and MongoGridFS classes are thread safe. Does this mean I can have a singleton instance of MongoClient or MongoDatabase?
The documentation also states that a connection pool is used for MongoClient, so the management of connections to MongoDB is abstracted from the MongoClient class anyway.
Example Scenario
Let's say I have three MongoDB instances in my replicaset; so I create MongoClient and MongoDatabase objects based upon the three server addresses for these instances. Can I create a static singleton for the database and client objects and use them across multiple requests simultaneously? What if one of the instances dies; if I cache the Mongo objects, how can I make sure this scenario is dealt with safely?
In my project I'm using a singleton MongoClient only, then get MongoServer and other stuff from MongoClient.
This is because what you said, the connection pool is in the MongoClient, I definitely don't want more than one connection pool. and here's what the document says:
When you are connecting to a replica set you will still use only one
instance of MongoClient, which represents the replica set as a whole.
The driver automatically finds all the members of the replica set and
identifies the current primary.
Actually the MongoClient is added to C# driver since 1.7, to represent the whole replica set and handle failover, load balancing stuff. Because MongoServer doesn't have the ability to to that. Thus you shouldn't cache MongoServer because once a server is offline you can't know it.
EDIT: Just had a look at the source code. I may have made a mistake. The MongoClient doesn't handle connection pool. the MongoServer does (at least until driver 1.7, haven't looked at the latest driver source yet). This makes sense because MongoServer represents a real Mongo instance. And one connection pool stores connections only to that server.

MysqlConnectionPoolDataSource or c3p0 like library?

What's the difference between MysqlConnectionPoolDataSource and C3p0, BoneCP or dbcp library for connection pooling? I don't understand why use a library if mysql connector give connection pooling.
A ConnectionPoolDataSource is not a connection pool (or at least: it shouldn't be), it is intended to be used by a DataSource that provides pooling (eg from an application server). A ConnectionPoolDataSource provides the physical connections that will be held in the connection pool. Besides creating those physical connections a ConnectionPoolDataSource shouldn't do anything else.
So if you are working in an application server, use the pooling provided by the DataSources of the application server. If you are in a standalone application or a server that doesn't provide datasources on its own, use third party connection pools like BoneCP, c3p0 or Apache DBCP. If MySQL also provides a normal DataSource that provides pooling, then you could use that.

Tomcat 7 connection pool / JPA : Getting a specific connection

I am using JPA together with the Tomcat 7 connection pool.
How is it possible to specify that the EntityManager injected (by Spring in this case) into a data access object should use a specific connection from the pool, not one taken at random?
In other words, the requirement is to initialize specific connections in the pool (so these connections see the database pre-configured in various states), to then 'label' these connections and to then get EntityManager / the transaction to use the connection with a specific label.
I know that Oracle UCP offers similar functionality, but we have had issues with that so we want to do the same thing with the Tomcat pool.
Thanks !

Resources