I have a problem with a ConnectionPool that gets exausted very quickly.
Basically i have loaded a listener within the application, whenever the context is initialized, a Timer will start, and a timertask within it, will perform an SQL query, which uses a connection pool “the connection pool jar i copied it in Tomcat 6”
The listener “only the relevant method”:
private MyTask task=new MyTask();
public void contextInitialized(ServletContextEvent event) {
this.ctx=event.getServletContext();
Timer timer= new Timer();
Calendar calendar=Calendar.getInstance();
Date firstTime=calendar.getTime();
timer.scheduleAtFixedRate(task, firstTime, 1000*60);
ctx.setAttribute("timer",timer);
}
The connection pool:
public class ConnectionPool {
private static ConnectionPool pool=null;
private static DataSource source=null;
/**
* Private constructor
* Private omdat dit klasse een singleton-patroon volgd, dus nooit meer dan een instantie is toegestaan.
*/
private ConnectionPool(){
try{
InitialContext ini=new InitialContext();
source=(DataSource)ini.lookup("java:/comp/env/jdbc/verkocht");
}catch(Exception e){
System.out.println("Verkocht db not found");//bedoelt voor test
e.printStackTrace();
}
}
/**
* Singleton getInstance() methode
* @return the connection pool
*/
public static ConnectionPool getInstance(){
if(pool==null){
pool=new ConnectionPool();
}
return pool;
}
/**
* Deze methode returneert een Connection instantie uit het pool
* @return the Connection
*/
public Connection getConnection(){
try{
return source.getConnection();
}catch(SQLException e){
System.out.println("No connection estabilished");
e.printStackTrace();
return null;
}
}
/**
* Sluid deze Connection object
* @param Een connection instantie
*/
public void freeConnection(Connection c){
try{
c.close();
} catch(SQLException e){
e.printStackTrace();
}
}
public static void main(String[] args){
ConnectionPool con=ConnectionPool.getInstance();
con.getConnection();
}
}
Basically I get the null pointer at this line:
return source.getConnection();
Telling me that the database name is not found.
The problems is that it works for the first times, for 5 or 6 minutes (when I set the timer to 1000*60) the queries are sent successfully, so the database is found, meaning that the configuration in context.xml is correct.
The method that is using the connection pool from inside the overridden run method of MyTask, which extends TimerTask is:
public void assign(int toegewezenAan, double verkoopPrijs, double totaalAfgetrokken, int artikelId){
String sqlUpdate="UPDATE artikelen SET toegewezenAan=?, verkoopPrijs=?, totaalAfgetrokken=?, status=? WHERE artikelId=?";
ConnectionPool pool=ConnectionPool.getInstance();
Connection con=pool.getConnection();
PreparedStatement prep=null;
try{
prep=con.prepareStatement(sqlUpdate);
prep.setInt(1,toegewezenAan);
prep.setDouble(2, verkoopPrijs);
prep.setDouble(3,totaalAfgetrokken);
prep.setString(4, "VERKOCHT");
prep.setInt(5, artikelId);
prep.executeUpdate();
} catch(SQLException e){
e.printStackTrace();
pool.freeConnection(con);
}
}
Any advice?
You only free the connection in the catch-Block, but you actually need to free it everytime.
You should put it in a finally block, so that the connection is freed (and returned to the pool) after each use.
And you should call
prep.close()in the finally to close the PreparedStatement (ifpool.freeConnection(con)does not take of this itself)).