Link to home
Start Free TrialLog in
Avatar of osiruz
osiruz

asked on

DBConnection Pool getConnection returns null

Hi,

I've reused the DBConnection Pool Manager class implemented by someone else. I tested it on my development machine and it works fine but once i rolled it out to production, sometimes i'm getting a null from the getConnection() method. This does not happen all the time, sometimes it works other times it fails. This makes troubleshooting task difficult as I can't identify in what scenario it may fail.

Here's a snippet of my codes where it fails :
--------------------------------------
 DBConnectionManager objConnMgr = null;
 objConnMgr = DBConnectionManager.getInstance();
 con = objConnMgr.getConnection("oracle");

* con returned is null.

Does anyone know what are the possible reasons of getting null in the con object?
Avatar of flumpman
flumpman

How many threads are accessing the DBConnectionManager class?  If multiple threads are accessing it then it could be a synchronization issue.

If you are using multiple threads, then try synchronizing the getConnection method and see if that works.

It could also be because of other reasons - perhaps the database is running out of connections?

--
flumpman
Avatar of osiruz

ASKER

How can i tell the number of threads accessing the DBConnection class? and how do i synchronize it if that's the problem? Pls. advise.

I'm just a beginner at this DBConnection pool thing, pls. excuse me if I am posting some questions which may sound silly. Thanks for the help.
ASKER CERTIFIED SOLUTION
Avatar of flumpman
flumpman

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of osiruz

ASKER

I'm using it for my web application (JSPs mainly and some servlets)
Ok, so it is going to be accessed by multiple threads at one time.

You need to check if the getConnection method is synchronized.  This would have the signature something like

public synchronized Connection getConnection(String name)

as opposed to

public Connection getConnection(String name)

The "synchronized" keyword means that a monitor (lock) on the object is required to call that method.  Only one thread can hold the monitor at one time, resulting in only one thread being able to access any of the synchronized methods of that object at one time.

If it isn't synchronized then you could change the signature and recompile to see if that has any effect.  If you don't have the source code then you could synchronize on the instance of the object by using a synchronized code block.

e.g.

DBConnectionManager objConnMgr = null;
objConnMgr = DBConnectionManager.getInstance();
synchronized (objConnMgr) {
    con = objConnMgr.getConnection("oracle");
    ...
}

I would really recommend that you read the Threads section of the Java Tutorial.  These concepts are fundamental to Java and especially relevant when developing web applications.

--
flumpman
Avatar of osiruz

ASKER

Thanks for the feedback.

I've checked codes, the getInstance() returns a synchronized DBConnectionManager.

===================================
static synchronized public DBConnectionManager getInstance() {
        if (objInstance == null) {
            objInstance = new DBConnectionManager();
        }
        intClients++;
        return objInstance;
    }
===================================

but the getConnection() method is not synchronized.

===================================
 public Connection getConnection(String name) {
        DBConnectionPool objPool = (DBConnectionPool) hshPools.get(name);
        if (objPool != null) {
            return objPool.getConnection();
        }        
        return null;
    }

===================================

Will this be the reason why it fails to get a connection sometimes? Do i need to change the getConnection() method to synchronized? Thanks again for your help.

The getInstance method doesn't return a "synchronized DBConnectionManager", it returns a DBConnectionManager from a synchronized method.

The problem could reside in the getConnection method in the DBConnectionPool class.  It depends on what is happening inside this method (and if it synchronized).  Again you could see if the getConnection method is synchronized or you could synchronize on the objPool object.

e.g.

public synchronized Connection getConnection()

or

synchronized (objpool) {
    return objPool.getConnection();
}

The first way is preferable as it ensures that any code calling the getConnection method acquires a lock first.  The second method will only work as long as the only way of getting a connection is through the getConnection(String) method of the DBConnectionManager class.

--
flumpman
Avatar of girionis
 If you are running it with Servlets you do not need to synchronize the methods, only instance variables. Servelts are synchronized by default and every new request will create a new thread to handle uit. Each thread will have its own copy of the getConnection method. If you have instance variables synchronize them to avoid possible problems.

  Why not have a static method that returns a connection object?

public static Conenction getConnection()
{
...
...
}

The getConnection method is not in the servlet but in a singleton instance.  Therefore synchronization is necessary...

--
flumpman
Why does it need to be synchronized? I don't see any reason that it should.
And from the description of the problem, synchronising isn't going to make any difference.

I'd say your problem is that either you have created a connection pool named "oracle" or your connection pool is running out of available connections. Check that you set up your connection pool(s) correctly.
Avatar of osiruz

ASKER

i've checked the logs it seems like I'm able to get the objPool but the connection itself is null.

The log "Returning valid connection" is being logged, but i suspect the objPool.getConnection() itself is returning null.

Does anyone knows what might be the error when having a valid objPool but there's no connection available in the pool? Run out of connections maybe? If so, how do I check how many connections is left available in the pool?

Pls help.

------------------------------------------------
  public synchronized Connection getConnection(String name) {
        DBConnectionPool objPool = (DBConnectionPool) hshPools.get(name);
        if (objPool != null) {
            log("Returning valid connection");
            return objPool.getConnection();
        }
        else
        {
             log("getConnection(str) is null");
        }
        return null;
    }
As I mentioned above your pool may be empty and unable to create new connections. Whose connection pool implementation are you using? I'd recomend checking the documentation and configuration of your pooling.

Avatar of osiruz

ASKER

now i'm getting this error instead,

java.sql.SQLException: Io exception: Broken pipe

does anyone knows, what could this be due to?
The javadoc for the method you are using states that it returns null if the maximum number of connections has already been reached.:

/**
* Returns an open connection. If no one is available, and the max
* number of connections has not been reached, a new connection is
* created.
*
* @param name The pool name as defined in the properties file
* @return Connection The connection or null
*/

There is a similiar method that waits until a connection is available, but may still return null if a connection does not become available within timelimit:

/**
* Returns an open connection. If no one is available, and the max
* number of connections has not been reached, a new connection is
* created. If the max number has been reached, waits until one
* is available or the specified time has elapsed.
*
* @param name The pool name as defined in the properties file
* @param time The number of milliseconds to wait
* @return Connection The connection or null
*/

You could also try increasing the max number of exceptions in the properties file.
> now i'm getting this error instead,

What did you change?

The error sounds like connection to the db maybe getting lost.
Avatar of osiruz

ASKER

I did not change anything. after i restart my webserver everything is back to normal again. I forsee that the first error ( getconnection() returns null ) may happen again after some tine.
I'm sure it will, once all your connections in your pool are used up.
Increase the max number of connections and ensure you are returning connections to the pool once finished with.
Avatar of osiruz

ASKER

Thanks for your help.

I'd replaced the entire DBConnection class instead. It is working fine now.