richardsimnett
asked on
Question about closing a glassfish jdbc connection pool connection
Hello,
I have a database handler called glassfishDB, it handles database queries for a servlet I wrote. Anyways, Ive been noticing that after awhile the servlet stops responding, so started to debug and came up with this:
----Log File Rotated---
RAR5117 : Failed to obtain/create connection from connection pool [ tracking ]. Reason : In-use connections equal max-pool-size and expired max-wait-time. Cannot allocate more connections.
RAR5114 : Error allocating connection : [Error in allocating a connection. Cause: In-use connections equal max-pool-size and expired max-wait-time. Cannot allocate more connections.]
Database Close Error: java.lang.NullPointerExcep tion
StandardWrapperValve[xmlDa taServices ]: PWC1406: Servlet.service() for servlet xmlDataServices threw exception
java.lang.NullPointerExcep tion
at xmlDataServices.getServerI D(xmlDataS ervices.ja va:170)
at xmlDataServices.processReq uest(xmlDa taServices .java:46)
at xmlDataServices.doPost(xml DataServic es.java:33 1)
at javax.servlet.http.HttpSer vlet.servi ce(HttpSer vlet.java: 738)
at javax.servlet.http.HttpSer vlet.servi ce(HttpSer vlet.java: 831)
at org.apache.catalina.core.A pplication FilterChai n.servletS ervice(App licationFi lterChain. java:411)
at org.apache.catalina.core.A pplication FilterChai n.internal DoFilter(A pplication FilterChai n.java:317 )
which obviously indicates that the servlet cant run because it cant get a database connection. So I went back to my servlet and glassfishDB class, and started poking around. In the servlet, all the db calls are closed when they are done being used - so that was one issue out of the way, the only other thing I can come up with is that I am not closing the connections down properly. Can someone please tell me how to fix this error? The code for my glassfishDB is below and here is an example of its usage:
glassfishDB db = new glassfishDB("jdbc/tracking _pool");
db.executeQuery("select * from sometable");
db.close();
or the same thing but with an update you dont need to close, as it closes automatically:
db.executeUpdate("update sometable set somecolumn = 'somevalue'");
Worth 500 points.
Thanks,
Rick
I have a database handler called glassfishDB, it handles database queries for a servlet I wrote. Anyways, Ive been noticing that after awhile the servlet stops responding, so started to debug and came up with this:
----Log File Rotated---
RAR5117 : Failed to obtain/create connection from connection pool [ tracking ]. Reason : In-use connections equal max-pool-size and expired max-wait-time. Cannot allocate more connections.
RAR5114 : Error allocating connection : [Error in allocating a connection. Cause: In-use connections equal max-pool-size and expired max-wait-time. Cannot allocate more connections.]
Database Close Error: java.lang.NullPointerExcep
StandardWrapperValve[xmlDa
java.lang.NullPointerExcep
at xmlDataServices.getServerI
at xmlDataServices.processReq
at xmlDataServices.doPost(xml
at javax.servlet.http.HttpSer
at javax.servlet.http.HttpSer
at org.apache.catalina.core.A
at org.apache.catalina.core.A
which obviously indicates that the servlet cant run because it cant get a database connection. So I went back to my servlet and glassfishDB class, and started poking around. In the servlet, all the db calls are closed when they are done being used - so that was one issue out of the way, the only other thing I can come up with is that I am not closing the connections down properly. Can someone please tell me how to fix this error? The code for my glassfishDB is below and here is an example of its usage:
glassfishDB db = new glassfishDB("jdbc/tracking
db.executeQuery("select * from sometable");
db.close();
or the same thing but with an update you dont need to close, as it closes automatically:
db.executeUpdate("update sometable set somecolumn = 'somevalue'");
Worth 500 points.
Thanks,
Rick
/*
* Database.java
*
* Created on November 1, 2006, 1:28 AM
*
* To change this template, choose Tools | Template Manager
* and open the template in the editor.
*/
//Database Connectivity - Requires ODBC
import java.util.Hashtable;
import javax.sql.*;
import java.sql.*;
import javax.naming.*;
public class glassfishDB {
Statement stmt;
ResultSet rs;
ResultSetMetaData meta;
Connection con;
long numberofrows = -1;
int errorState = 0;
String errorMessage = "";
String poolname = "";
glassfishDB(String poolName)
{
this.poolname = poolName;
}
public static DataSource getDataSource(String dsName) throws NamingException
{
InitialContext context = null;
context = new InitialContext();
DataSource dataSource = (DataSource) context.lookup("jdbc/" + dsName);
return dataSource;
}
void executeQuery(String query)
{
try
{
DataSource ds = getDataSource(poolname);
con = ds.getConnection();
stmt = con.createStatement();
// Do db operations.
// Do not close driver connection
rs = stmt.executeQuery(query);
rs.setFetchSize(1);
meta = rs.getMetaData();
}
catch (Exception e)
{
//System.out.println("Database Connection Error:" + e.toString());
errorMessage = e.toString();
errorState = 1;
}
}
void executeUpdate(String query)
{
try
{
DataSource ds = getDataSource(poolname);
con = ds.getConnection();
stmt = con.createStatement();
stmt.executeUpdate(query);
con.close();
}
catch (Exception e)
{
//System.out.println("Database Connection Error:" + e.toString());
errorMessage = e.toString();
errorState = 2;
}
}
long getRowCount()
{
try
{
int start = rs.getRow();
rs.last();
int last = rs.getRow();
rs.first();
numberofrows = last - start;
}
catch(Exception e)
{
//System.out.println("Database getRowCount() Error: " + e.toString());
errorMessage = e.toString();
errorState = 3;
}
return numberofrows;
}
synchronized Hashtable getNextRecord()
{
Hashtable ht = new Hashtable();
//Assign the next record to the hashtable
try
{
if (rs.next())
{
////System.out.println("Data Present");
//loop over the variable names and assign them and their values to the hashtable
for (int col = 1; col <= meta.getColumnCount(); col++) {
String varName = meta.getColumnName(col).trim();
////System.out.println("ColNAME " +varName);
String tdata = rs.getString(col);
if (tdata == null)
tdata = "";
ht.put(varName, tdata);
}
}
else
{
ht = null;
}
}
catch (Exception e)
{
//System.out.println("Database Read Error: " + e.toString());
errorMessage = e.toString();
errorState = 4;
}
return ht;
}
void close()
{
try
{
con.close();
}
catch (Exception e)
{
System.out.print("Database Close Error: " + e.toString() + "\n\n");
}
}
}
ASKER
yes I do close after the update in the executeUpdate statement... my thought is that maybe Im not closing the conenction properly in the close() function - but I cant seem to put my finger on what exactly is wrong.
Thanks,
Rick
Thanks,
Rick
It seems almost certain that you're not closing the connections properly. What is the code you have for closing a db connection?
ASKER
void close()
{
try
{
con.close();
}
catch (Exception e)
{
System.out.print("Database Close Error: " + e.toString() + "\n\n");
}
}
{
try
{
con.close();
}
catch (Exception e)
{
System.out.print("Database
}
}
ASKER
I read somewhere to only close the con, never anything else, or it will result in the connection in the connection pool being closed, which negates the positive effect of using a pool in the first place.
con.close() looks good. We always close the resultset, too, but closing the connection should be fine. Do you see a lot of Database Close Error messages in your logs? That would indicate that the connection couldn't be closed for some reason.
Is it possible that your connection pool is defined for more connections than your db accepts? How many connections do you have in your pool, and how many does your db allow?
Is it possible that your connection pool is defined for more connections than your db accepts? How many connections do you have in your pool, and how many does your db allow?
ASKER
there are no close errors reported at all in any of the logs, the glassfish logs are clear as well until I hit the connection pool errors... the connection pool is configured to allow a minimum of 8 connections and a maximum of 32 concurrent. The mysql server is set to allow a maximum of 512 concurrent connections. So the connections shouldnt be an issue, its just the fact that Im not properly freeing the connection pool connections somewhere...
Im going to try closing the result set and seeing what happens over time. Ill let you know in about 45 minutes if that worked (it typically takes that long for the servlet to start failing).
Thanks,
Rick
Im going to try closing the result set and seeing what happens over time. Ill let you know in about 45 minutes if that worked (it typically takes that long for the servlet to start failing).
Thanks,
Rick
There was a bug last year in glassfish around closing nested get connection calls:
https://glassfish.dev.java.net/issues/show_bug.cgi?id=3279
It's been fixed, but is it possible that your version of glassfish doesn't have this fix? You can see the version of glassfish with the fix at the bottom of the bug page.
https://glassfish.dev.java.net/issues/show_bug.cgi?id=3279
It's been fixed, but is it possible that your version of glassfish doesn't have this fix? You can see the version of glassfish with the fix at the bottom of the bug page.
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
ok, still the same error when I close the rs in addition to the con. I looked at the bug you showed, and to be honest, I just installed my copy of glassfish last month, it was bundled with netbeans. Plus I get the same error on our production servers, which I know to be completely up to date, so I dont think it is the issue.
Thanks,
Rick
Thanks,
Rick
ASKER
checked the versions here is what is on both: glassfish-v2-b58g
should be up to par, as b56 was the fixed version
should be up to par, as b56 was the fixed version
ASKER
ok... its fixed. Im not sure why the exception is being thrown yet, but you were right somewhere that I execute the executeUpdate() function an exception is being generated that was not being checked for, and because of it the close statement never executed... when I mvoed the close() call into a finally statment it stopped messing up.
Thanks for the help! I wouldnt have figured this out withour your suggestions.
Thanks again!
Thanks for the help! I wouldnt have figured this out withour your suggestions.
Thanks again!
In fact, now that you've confirmed the glassfish version, and you think that there are enough MySQL connections for your app, then I'd start debugging the connections and the closes. Write to a log with every getConnection and with every close, and see if they match up. It might help you track down where you are not closing connections, or where exceptions are occurring to prevent your close() from being called.
ASKER
Yeah, thats what Im actually doing... Its stupid errors, XML data paths that werent updated after some changes and totally overlooked, are causing invalid queries to be created, which throw an exception, and were causing the connections to not close properly on update. I think I got it now.
Thanks again!
Thanks again!
Great -- congrats on tracking that down. When I posted that last comment, I didn't realize that you'd already closed the question.
For normal JDBC connections, on update the resultset is closed (in a sense) but the database connection itself exists and has to be closed.