home *** CD-ROM | disk | FTP | other *** search
/ io Programmo 77 / IOPROG_77.ISO / tips / Java / ConnectionPool / src / it / favaroni / db / connectionpool / ConnectionPool.java < prev    next >
Encoding:
Java Source  |  2003-12-19  |  8.5 KB  |  215 lines

  1. package it.favaroni.db.connectionpool;
  2.  
  3. /**
  4.  * Gestore del pool di connessioni.
  5.  * Data di creazione: (26/06/2003 10.04.45)
  6.  * @author: Roberto Favaroni
  7.  */
  8. import java.util.*;
  9. import java.sql.*;
  10. import it.favaroni.wrapper.PropertiesFileHandler;
  11. import org.apache.log4j.*;
  12.  
  13. public class ConnectionPool {
  14.     private static ConnectionPool connectionPool = null;
  15.     private Hashtable pool = new Hashtable();
  16.     private ConnectionManager connectionManager = null;
  17.     private ConnectionParameters connectionParameters = new ConnectionParameters();
  18.     private Logger logger = null;
  19. /**
  20.  * Commento del constructor ConnectionPool.
  21.  */
  22. private ConnectionPool() {
  23.     super();
  24.     try {
  25.         //configurazione log4j
  26.         PropertiesFileHandler props = PropertiesFileHandler.getInstance("connectionpool.properties");        
  27.         setLogger(Logger.getLogger(this.getClass().getName()));
  28.         PropertyConfigurator.configure(props.readProperty("log4j.file.url"));
  29.                 
  30.         getLogger().info("creazione istanza ConnectionPool");
  31.         getLogger().info("acquisizione parametri dal file di properties");                
  32.          //acquisizione parametri dal file di properties   
  33.         getConnectionParameters().setDriver(props.readProperty("jdbc.driver"));
  34.         getConnectionParameters().setUrl(props.readProperty("jdbc.url"));
  35.         getConnectionParameters().setUser(props.readProperty("jdbc.user"));
  36.         getConnectionParameters().setPassword(props.readProperty("jdbc.password"));
  37.         getConnectionParameters().setMinConns(Integer.parseInt(props.readProperty("pool.minConns")));
  38.         getConnectionParameters().setMaxConns(Integer.parseInt(props.readProperty("pool.maxConns")));
  39.         getConnectionParameters().setMaxInUse(Integer.parseInt(props.readProperty("pool.maxInUse")));
  40.         getConnectionParameters().setCleaningInterval(Integer.parseInt(props.readProperty("manager.cleaningInterval")));                
  41.         
  42.         //lancio del connection manager
  43.         getLogger().info("creazione e partenza istanza ConnectionManager con intervallo di " + getConnectionParameters().getCleaningInterval() + " secondi" );        
  44.         connectionManager = new ConnectionManager(getConnectionParameters().getCleaningInterval());
  45.         getConnectionManager().setAlive(true);         
  46.         (new Thread(getConnectionManager()).start());
  47.  
  48.         //registrazione driver del dbms
  49.         Class.forName(getConnectionParameters().getDriver());
  50.         
  51.         //creazione pool di connessioni minimo
  52.         getLogger().info("creazione pool minimo di " + getConnectionParameters().getMinConns() + " connessioni");                        
  53.         for (int i = 0; i < getConnectionParameters().getMinConns(); i++) {
  54.             makeConnection();
  55.         }
  56.     } catch (Exception e) {
  57.         getLogger().fatal(e.getMessage());
  58.     }
  59. }
  60. void cleanPool() throws SQLException {
  61.     //ricerca connessioni appese
  62.     getLogger().info("start pulizia del pool");
  63.     for (Enumeration enum = getPool().elements(); enum.hasMoreElements();) {
  64.         ConnectionItem currItem = (ConnectionItem) enum.nextElement();
  65.         if (currItem.isInUse()) {
  66.             java.util.Date now = new java.util.Date();
  67.             long diff = now.getTime() - currItem.getDate().getTime();
  68.             if (diff > (getConnectionParameters().getMaxInUse() * 1000)) {
  69.                 //connessione aperta da pi∙ tempo rispetto al max stabilito
  70.                 //rilascio forzato della connessione
  71.                 getLogger().error("rilascio forzato della connessione con progressivo " + currItem.getCounter() + " aperta da " + (diff/1000) + " secondi rispetto al max stabilito di " + getConnectionParameters().getMaxInUse() + " secondi");
  72.                 releaseConnection(currItem.getConnection());
  73.             }
  74.         }
  75.     }
  76.     getLogger().info("stop pulizia del pool; connessioni esaminate: " + getPool().size());    
  77. }
  78. private void closeConnection(ConnectionItem currItem) throws SQLException {
  79.     //chiusura e rimozione dal pool della connessione
  80.     currItem.getConnection().close();
  81.     getLogger().info("chiusura e rimozione dal pool della Connection con progressivo " + currItem.getCounter());
  82.     getPool().remove(currItem.getConnection().toString());
  83.  
  84. }
  85. private void closePool() throws SQLException {
  86.     for (Enumeration enum = getPool().elements(); enum.hasMoreElements();) {
  87.         closeConnection((ConnectionItem) enum.nextElement());
  88.     }
  89. }
  90. protected void finalize() throws Throwable {
  91.     super.finalize();
  92.     getLogger().info("distruzione istanza ConnectionPool");    
  93.  
  94.     //stop del connection manager
  95.     getLogger().info("distruzione istanza ConnectionManager");    
  96.     getConnectionManager().setAlive(false);
  97.  
  98.     //libero il pool
  99.      closePool();
  100.      
  101. }
  102. /**
  103.  * 
  104.  * @return it.favaroni.db.connectionpool.ConnectionManager
  105.  */
  106. private ConnectionManager getConnectionManager() {
  107.     return connectionManager;
  108. }
  109. /**
  110.  * 
  111.  * @return it.favaroni.db.connectionpool.ConnectionParameters
  112.  */
  113. private ConnectionParameters getConnectionParameters() {
  114.     return connectionParameters;
  115. }
  116. public synchronized Connection getFreeConnection() throws SQLException, MaxNumberConnectionException {
  117.     //ricerca connessione non in uso
  118.     for (Enumeration enum = getPool().elements(); enum.hasMoreElements();) {
  119.         ConnectionItem currItem = (ConnectionItem) enum.nextElement();
  120.         if (!currItem.isInUse()) {
  121.             //aggiornamento pool
  122.             currItem.setInUse(true);
  123.             getPool().put(currItem.getConnection().toString(), currItem);
  124.             getLogger().info("acquisizione Connection con progressivo " + currItem.getCounter());
  125.             return currItem.getConnection();
  126.         }
  127.     }
  128.     //non Φ stata trovata connessione non in uso, creazione di una nuova
  129.     getLogger().info("connessione attualmente non disponibile; richiesta creazione istanza Connection");    
  130.     return makeConnection();
  131. }
  132. public static synchronized ConnectionPool getInstance() {
  133.     //gestione singola istanza della classe con pattern singleton
  134.     if (connectionPool == null) {
  135.         connectionPool = new ConnectionPool();
  136.     }
  137.     return connectionPool;
  138. }
  139. /**
  140.  * 
  141.  * @return org.apache.log4j.Logger
  142.  */
  143. private org.apache.log4j.Logger getLogger() {
  144.     return logger;
  145. }
  146. /**
  147.  * 
  148.  * @return java.util.Hashtable
  149.  */
  150. private java.util.Hashtable getPool() {
  151.     return pool;
  152. }
  153. private Connection makeConnection() throws SQLException, MaxNumberConnectionException {
  154.     Connection newConnection = null;
  155.     //controllo su limite max stabilito di connessioni
  156.     if (getConnectionParameters().getMaxConns() == getPool().size()) {
  157.         getLogger().error("richiesta connessione eccedente al numero max stabilito del pool");
  158.         throw new MaxNumberConnectionException();
  159.     }
  160.     //creazione connessione
  161.     newConnection =
  162.         DriverManager.getConnection(
  163.             getConnectionParameters().getUrl(),
  164.             getConnectionParameters().getUser(),
  165.             getConnectionParameters().getPassword());
  166.     //inserimento nel pool
  167.     releaseConnection(newConnection);
  168.     return newConnection;
  169. }
  170. public synchronized void releaseConnection(Connection connection) {
  171.     //estrazione dal pool dell'item corrispondente
  172.     ConnectionItem currItem =
  173.         (ConnectionItem) getPool().get(connection.toString());
  174.     if (currItem == null) {
  175.         //ConnectionItem non trovato se richiamato da makeConnection per inizializzare l'item
  176.         currItem = new ConnectionItem();
  177.         currItem.setConnection(connection);
  178.         currItem.setCounter(getPool().size() + 1);
  179.         getLogger().info("creazione e apertura istanza Connection con progressivo: " + currItem.getCounter());
  180.     }
  181.     //aggiornamento del pool    
  182.     currItem.setInUse(false);
  183.     getPool().put(connection.toString(), currItem);
  184.     getLogger().info("rilascio istanza Connection con progressivo " + currItem.getCounter());
  185. }
  186. /**
  187.  * 
  188.  * @param newConnectionManager it.favaroni.db.connectionpool.ConnectionManager
  189.  */
  190. private void setConnectionManager(ConnectionManager newConnectionManager) {
  191.     connectionManager = newConnectionManager;
  192. }
  193. /**
  194.  * 
  195.  * @param newConnectionParameters it.favaroni.db.connectionpool.ConnectionParameters
  196.  */
  197. private void setConnectionParameters(ConnectionParameters newConnectionParameters) {
  198.     connectionParameters = newConnectionParameters;
  199. }
  200. /**
  201.  * 
  202.  * @param newLogger org.apache.log4j.Logger
  203.  */
  204. private void setLogger(org.apache.log4j.Logger newLogger) {
  205.     logger = newLogger;
  206. }
  207. /**
  208.  * 
  209.  * @param newPool java.util.Hashtable
  210.  */
  211. private void setPool(java.util.Hashtable newPool) {
  212.     pool = newPool;
  213. }
  214. }
  215.