Problem przepełnienia wydzielonej puli połączeń (JDBC Connection Pool),niezamknięte połączenia, zasoby JNDI

Tomcat nie ma kontroli nad cyklem życia zasobów JNDI, działa na zasadzie sam sobie utworzyłem sam po sobie i posprzątam. W odniesieniu do puli połączeń, oznacza to, że metoda close() nie jest wywoływana, w czasie startu/restartu serwera. Serwer bazy danych nie zawsze może stwierdzić ze na stronie klienta gniazdo (socket) został zamknięty w trybie pilnym, i utrzymuje otwarte połączenie (zombi connection). Zombi połączenia zajmują miejsce w wydzielonej puli połączeń GlobalNamingResources co może doprowadzić do jej przepełnienia. Najprostszym rozwiązaniem jest umieszczenie w konfiguracji serwera Listenera cyklu życia Tomcat, który zamknie połączenia za każdym razem, gdy cykl życiowy serwera zostanie przerwany.
Tworzymy class ServerListener pakujemy go do archiwum .jar , i wrzucamy do katalogu $CATALINA_HOME/lib

ServerListener

package com.ws.sjn;

import java.sql.SQLException;

import javax.naming.Context;
import javax.naming.NamingException;

import org.apache.catalina.Lifecycle;
import org.apache.catalina.LifecycleEvent;
import org.apache.catalina.LifecycleListener;
import org.apache.catalina.core.StandardServer;
import org.apache.tomcat.dbcp.dbcp.BasicDataSource;

public class ServerListener implements LifecycleListener {

 private String dataSourceName;

 public void lifecycleEvent(LifecycleEvent event) {

   if (!Lifecycle.AFTER_STOP_EVENT.equals(event.getType())) {
      return;
   }
   Object source = event.getSource();
   if (!(source instanceof StandardServer)) {
     return;
   }
   StandardServer server = (StandardServer)source;
   Context globalNamingContext = server.getGlobalNamingContext();

   BasicDataSource ds;
   try {
      ds = (BasicDataSource) globalNamingContext.lookup(dataSourceName);
   } catch (NamingException e) {
      throw new RuntimeException(e);
   }
   if (ds == null) {
      throw new RuntimeException("Cannot find Datasource: " + dataSourceName);
   }
   try {
      ds.close();
   } catch (SQLException e) {
      throw new RuntimeException("Cannot close Datasource: " + dataSourceName) ;
  }
}

   public void setDataSourceName(String dataSourceName) {
      this.dataSourceName = dataSourceName;
   }
}

Inicjalizujemy listener w konfiguracji serwera wskazując dataSourceName puli połączeń.
Do pliku konfiguracji $CATALINA_HOME/conf/server.xml dopisujemy: <!-- Close connection when tomcat shutdown -->
<Listener className="com.ws.sjn.ServerListener" dataSourceName="jdbc/myDatabase" />
Koniec .....
Artykuł napisany w wolnym czasie, prawa autorskie W.S.
Wsparcie finansowe Autora Artykułu :