Avoid clients keeping reference of a connection while implementing a connection Pool - java

I have implemented a connection pool. All is good. Now If a client borrows a connection and even returns it to the pool but the client also keeps the reference of this connection with him. Now, if pool returns same connection to another client; this will lead to same connection being used by multiple people.
How can I avoid that ?

Do not return the underlying connection object, but another object which wraps it. Within that object (using some kind of private property) store the state of that object; is it still available for use, or has it been invalidated by being returned to the pool or some other condition like being timed out). Then you can intercept any method call that attempts to use it and check against its state. If it is no longer available for use, throw an exception.
The wrapped connection object will also need to be private, so that the client cannot access it directly.
You will have one wrapper per client, but two or more wrappers may share the underlying connection object. But because you are storing state per client, only one client can use the object at one time.
Edited to include an untested example - which now shows a big problem with my approach.
Assuming you are returning something which implements java.sql.Connection, you could return instances of the below class.
package same.package.as.your.pool; // so your pool has access to set isValidConnection
import java.sql.Connection;
class MyConnection implements Connection {
private Connection actualConnection;
private boolean isValidConnection = false;
MyConnection(Connection conn) {
// package acccess for pool class to create connection
actualConnection = conn;
isValidConnection = true;
}
public boolean getIsValidConnection() {
return isValidConnection;
}
void setIsValidConnection(boolean isValid) {
// pool class can call this to invalidate when returned to pool or timed out
isValidConnection = isValid;
}
// intercept java.sql.Connection methods, checking if connection is still valid first
// for example
PreparedStatement prepareStatement(String sql) {
if (! isValidConnection) {
// WHAT TO DO HERE?
}
return actualConnection.prepareStatement(sql);
}
// ... and the rest
First big problem is that - ideally you would throw an Exception from the methods like prepareStatement when the connection is no longer valid because it's been returned to the pool. But because you are constrained by the caught exceptions of the original interface (in this case, throws SQLException) you'd either need to throw an SQLException (yuk, it isn't really an SQLException) or an uncaught exception (yuk - client code would probably want to catch the case where the pooled connection is not longer valid) or something else :-)
Two other issues with the code above - package access to protect the methods meant to be only available to your pool code is not very robust. Maybe you could create the MyConnection code as some kind of inner class within your pool code. Finally, having to override all java.sql.Connection interface would be a pain.
}

Related

How to implement connection management?

I need to create a class that handles connection methods. But I read online different ways to implement this.There are
Singleton
static method
1) Singleton like this example:
public SingletonHome{
private static SingletomHome s=null;
private SingletonHome(){
}
public static SingletongHome getInstance(){
//return instance s
}
public Connection getConnection(){
//return connection;
}
}
2) Use static method
public class Example{
public static Connection getConnection(){
//return connection;
}
}
Who is the best solution in an enviroment that uses connection pool, I get connection from the connection pool and after I need to handles these.Anyone can help me?
These two ways are not designed to be switched.
Suppose you need to change to another implementation, with Example.getConnection() or SingletonHome.getInstance().getConnection() you are stuck.
Besides these classes are not straight testable either.
You should really introduce an interface that defines operations required for a connection management.
And if your environment allows that, you should favor dependency injection to define and inject your singleton over the classical singleton pattern : it provides a lower coupling for clients.
Note that reinventing the wheel is never a good idea either and is never free bugs : libraries that handle for you the database connection management/pooling exist : commons-dbcp, HikariCP and others... You could probably not do better than these.
Use Pooling mechanism instead of these ways

Using try-with-resources in multiple methods with same AutoCloseable Object

I am trying to modularize my code but it involves passing around my object that implements AutoCloseable. Let say I have two public methods foo1 and foo2:
public class MyClass {
public void foo1() {
// Connection implements AutoCloseable
try (Connection conn = createConnection()) {
foo2(conn);
// is the connection closed or the behavior unpredictable?
conn.doSomethingElse();
}
}
public void foo2(Connection conn) {
try (conn) {
// do something with the Connection
}
}
}
I want to call foo2 from foo1, but also allow other classes to use foo2 separately.
public class OtherClass {
public void doSomething() {
MyClass myClass = new MyClass();
myClass.foo2(createConnection());
}
}
Does this lead to the connection being closed in foo1() after the call to foo2? Or should I put the try-with-resources in the calling methods (such as the doSomething() in OtherClass)?
Your foo1 method closes the connection after foo2 has used it. There is no need for foo2 to close the connection and it shouldn't. You're making it have an unexpected side-effect. E.g. when you call conn.doSomethingElse() inside foo1, you will find it won't work because the connection has been closed by the call to foo2. It's a violation of the principle of least astonishment because the method name does not reveal this side-effect.
If you called it foo2AndCloseTheConnection then you make clear what it does, but I recommend following the rule of thumb that the method that creates the closeable should be the only one to close it. If you follow this consistently, you'll never need to look inside a function to see whether or not something you've opened is closed by that function. You'll simply close it yourself explicitly.
If you want foo2 to be called from other methods, you need to make those methods close the connection:
public void doSomething() {
MyClass myClass = new MyClass();
try (Connection connection = createConnection()) {
myClass.foo2(connection);
}
}
Yes, foo2 closes the connection so it will be invalid when control returns to foo1. Nothing unpredictable about it.
It's a good rule to have things closed by the same code that creates them. But it would be good to be able to nest these things and let them share the same connection and transaction. One solution would be to have each of these data accessing methods receive the connection as a parameter and have an outer layer that gets the connection and makes sure it gets closed.
You're basically trying to reinvent Spring a bit at a time. Spring gives you the ability to have services that can use the same connection and lets you control how and whether transactions are propagated between them. This is done using AOP to wrap objects with around advice that gets the current connection for the thread from a threadlocal data structure. Much easier to use spring (or whatever container).

java.io.NotSerializableException: com.mysql.jdbc.DatabaseMetaData

I am using JSF 1.2 and am trying to use <a4j:keepAlive beanName="reportController">, but I keep on getting this error:
HTTP Status 500
Caused by: java.io.NotSerializableException: com.mysql.jdbc.DatabaseMetaData at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1183
I am trying to use <a4j:keepAlive beanName="reportController"> because when I search for a specific report and then try to sort the data in the dataTable, it seems that it loses all the data in the dataTable.
Caused by: java.io.NotSerializableException: com.mysql.jdbc.DatabaseMetaData
This will happen when you get hold of java.sql.Connection or even directly DatabaseMetaData as instance variable of a serializable class like below.
public class ReportController implements Serializable {
private Connection connection; // BAD!!
private DatabaseMetaData metadata; // BAD!!
// ...
}
You're not supposed to declare and get hold of external resources such as java.sql.Connection, Statement and ResultSet nor its properties as instance variables of a class. You should acquire, use and close them as soon as possible, exclusively within the method local scope. Get rid of those instance variables from the ReportController bean, move them into method local scope and this problem shall disappear. Only having DataSource (the server-managed connection pool) as instance variable is OK.
public class ReportController implements Serializable {
#Resource("jdbc/someDB")
private DataSource dataSource;
public void someMethod() {
try (Connection connection = dataSource.getConnection()) { // OK.
// ...
}
}
// ...
}
The <a4j:keepAlive> isn't exactly the cause of this problem. It just remembers the bean instance in the HTTP session across HTTP postback requests on the same page. HTTP session attributes are inherently usually serialized. This serialization merely triggered and exposed your hidden design problem. Volatile one-time-use resources such as database connection, statement, metadata, inputstream, outputstream, etc are absolutely not supposed to be serializable and hence this exception.
See also:
Is it safe to use a static java.sql.Connection instance in a multithreaded system?
Returning a ResultSet

Playframework 1.2.5 and JDBI

I am trying to use JDBI with Play 1.2.5 and im having a problem with running out of database connections. I am using the H2 in-memory database (in application.conf, db=mem)
I have created class to obtain jdbi instances that uses Play's DB.datasource like so:
public class Database {
private static DataSource ds = DB.datasource;
private static DBI getDatabase() {
return new DBI(ds);
}
public static <T> T withDatabase(HandleCallback<T> hc) {
return getDatabase().withHandle(hc);
}
public static <T> T withTransaction(TransactionCallback<T> tc) {
return getDatabase().inTransaction(tc);
}
}
Every time I do a database call, a new DBI instance is created but it always wraps the same static DataSource object (play.db.DB.datasource)
Whats happening is, after a while I am getting the following:
CallbackFailedException occured : org.skife.jdbi.v2.exceptions.UnableToObtainConnectionException: java.sql.SQLException: An attempt by a client to checkout a Connection has timed out.
I am confused because the whole point of DBI.withHandle() and DBI.withTransaction() is to close the connection and free up resources when the callback method completes.
I also tried making getDatabase() return the same DBI instance every time, but the same problem occured.
What am I doing wrong?
Duh. Turns out I was leaking connections in some old code that wasn't using withHandle(). As soon as I upgraded it the problem stopped
From the official documentation
Because Handle holds an open connection, care must be taken to ensure that each handle is closed when you are done with it. Failure to close Handles will eventually overwhelm your database with open connections, or drain your connection pool.
Turns out you are not guaranteeing the closing of the handle in your callback function whenever it is provided.

How to keep SSH connection available?

I'm writing an application which uses sshj library for SSH connections. User opens Connect Dialog from menu, types login data and clicks Connect button to establish a connection. Then the user performs various operations from different panels and frames. My question is: where should I keep this connection to make it available to every panel and frame that needs it until the user clicks Disconnect button? I thought about static field in some custom class but I'm not convinced to do so. What are your ideas?
It sounds like you are interested in some type of pool.
You can do this in different ways. One way is to have a class that handles all the connections, which is a singleton, sort of. Then you simply ask the pool for a connection, for instance
SSHConnection con = ConnectionPool.getConnection(host, port);
You could also use a proxy for this. In a proxy, you actually get a placeholder instead of the actual connection. The proxy shares information with other instances, sort of like
class ConnectionProxy {
private static SSHConnection connection;
}
the connection variable is shared, and when you create a new ConnectionProxy, you will actually get the old connection, but it looks like you get a new connection.
Another option is to simply pass the instance around to all classes that needs it. This will allow you to keep track of who does what, but you will loose the flexibility of getting a connection from wherever you want.
Passing an instance around will help if you are debugging though, think of it like this. You are in a crowded room and you have a some money laying in a box that needs a key to open. If you hand that key to one person (the class that needs it) and leave the room and come back and the money is gone, you can blame that person. If instead you just leave the key on the table next to the box (the instance is global) and leave the room, come back and the money is gone, then good luck finding out who took it.
References:
*] Proxy pattern - WikiPedia
Proxy example
More specifically, it could look something like this:
public class ConnectionProxy implements Connectable {
// where Connectable is some shared interface between ConnectionProxy
// and SSHConnection. The proxy should "look like" a connection, it just
// hides the actual connection behind the scenes.
private static SSHConnection connection;
public ConnectionProxy() { }
public ConnectionProxy(String host, int port) {
connection = new SSHConnection(host, port);
}
public void connect(String host, int port) {
if (isConnected()) {
return;
}
connection = new SSHConnection(host, port);
}
public void reconnect() {
connection = new SSHConnection(connection.getHost(), connection.getPort());
}
public boolean isConnected() {
return connection != null && connection.isConnected();
}
}
You use the class by either instantiating it or connecting it.
class Program {
public void sendMessage() {
ConnectionProxy proxy = new ConnectionProxy();
if (!proxy.isConnected()) {
// I guess noone connected it
return;
}
proxy.sendBytes();
}
}
And in your connection dialog you instantiate or connect the ConnectionProxy. You could add support for several connections, i.e. different hosts and ports, just by making the variable connection a list instead, and checking the host and port for the right connection. You basically create a pool of connections, but to the client class it looks like it is creating the connection.
Doesn't matter where you put it, so long as you provide a getter method for retrieving it, and that getting method is public.
I think it's more a question of where it logically belongs. If it's a property of the application (as opposed to a window, frame, profile, whatever) put the getter in the main application class.
Design-wise, I'd recommend wrapping the operations you can perform over SSH in a separate class (RemoteCommands or some such), and injecting (setting as a property) an instance of this class everywhere you need to perform a remote command from.
If this seems like a lot of extra boilerplate code because every single frame and panel needs it, this shouldn't say "I need a global variable" to you. It should say "I should reduce the number of components that directly execute remote commands".

Categories