PoolData.java :  » Database-JDBC-Connection-Pool » Primrose » uk » org » primrose » pool » core » Java Open Source

Java Open Source » Database JDBC Connection Pool » Primrose 
Primrose » uk » org » primrose » pool » core » PoolData.java
/**
*  Library name : Primrose - A Java Database Connection Pool.
*  Published by Ben Keeping, http://primrose.org.uk .
*  Copyright (C) 2004 Ben Keeping, primrose.org.uk
*  Email: Use "Contact Us Form" on website
*
*  This library is free software; you can redistribute it and/or
*  modify it under the terms of the GNU Lesser General Public
*  License as published by the Free Software Foundation; either
*  version 2.1 of the License, or (at your option) any later version.
*
*  This library is distributed in the hope that it will be useful,
*  but WITHOUT ANY WARRANTY; without even the implied warranty of
*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
*  Lesser General Public License for more details.
*
*  You should have received a copy of the GNU Lesser General Public
*  License along with this library; if not, write to the Free Software
*  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

package uk.org.primrose.pool.core;
import uk.org.primrose.Logger;
import uk.org.primrose.Util;
import java.sql.*;
import java.util.*;
import java.io.*;

public class PoolData extends PoolConfigImpl {
  
  /*
   * A trivial synch object used by Pool.java
   */
  class PoolLock {}
  
  /**
   * 
   * @author sedj
   * On failover (if defined), then start a thread to monitor the broken
   * DB to see if it comes back. If it does, the thread stops, and informs the 
   * Pool to cut back from the failover pool to the original pool
   */
  class FailoverCutBack extends Thread {
    public FailoverCutBack(Pool pool, Logger logger) {
      this.pool = pool;
      this.logger = logger;
    }
    Pool pool = null;
    Logger logger = null;
    boolean bKeepRunning = true;

    public void run() {
      while (bKeepRunning) {
        try { Thread.sleep(10000); } catch (InterruptedException ie) {}
        Connection c = null;
        Statement s = null;
        ResultSet rs = null;
        try {
          c = Util.getConnection(driverClass, driverURL, user, password);
          s = c.createStatement();
          rs = s.executeQuery(onExceptionCheckSQL);
          logger.info("[FailoverCutBack@" +pool.getPoolName() +"] FailoverCutBack has determined that the original DB is back up ... informing pool to cut back");
          pool.cutbackFromFailoverPool();
          bKeepRunning = false;
        } catch (Throwable t) {          
        } finally {
          try { if (rs != null) rs.close(); } catch (SQLException sqle2) {}
          try { if (s != null) s.close(); } catch (SQLException sqle2) {}
          try { if (c != null) c.close(); } catch (SQLException sqle2) {}
        }
      }
    }
    
    public void stopIt() {
      bKeepRunning = false;
    }
  }

  // Global id for a connection
  protected long gid = 0L;

  
  // Connection status codes
  public static final int UNKNOWN_STATUS_CODE = -1;
  public static final int CONNECTION_ACTIVE = 1;
  public static final int CONNECTION_INACTIVE = 2;
  public static final int CONNECTION_DUMPED = 3;

  // Connection behviours
  public static final int ON_CLOSE_SHOULD_DIE = 4;
  public static final int ON_CLOSE_SHOULD_REUSE = 5;

  // A list of connections (and status's etc)
  Vector<ConnectionHolder> connections = null;

  // Whether the pool can give out connections
  boolean poolAccessLocked = false;

  // Global lock object
  protected PoolLock lock = null;

  // The number of waiting threads waiting for a connection
  protected int numberOfWaitingThreads = 0;
  protected int totalConnectionsHandedOut = 0;

  // A monitor on the pool
  PoolMonitor monitor = null;
  
  // The pool's logger
  protected Logger logger = null;
  
  // The pool to failover to (if specified)
  Pool failoverPoolObj = null;
  // A thread to monitor if this DB comes back (and cutback)
  FailoverCutBack failoverCutBackObj = null;
  
  // Is the pool shutdown ?
  boolean bPoolHasBeenShutdown = false;
  
  protected void setUpLogger() {
    logger = new Logger();
    if (log != null && log.length() > 0) {      
      try {
        logger.setEmailDetails(emailEvents, adminEmail, smtpMailExchangeServer, poolName);
        logger.setLogLevel(logLevel);
        logger.setLogWriter(log);
      } catch (IOException ioe) {
        System.out.println("Primrose cannot write to log file : " +log);
        ioe.printStackTrace();
      }
      
    }
  
  }
  
  /**
  *  Get the number of waiting threads
  */
  public int getNumberOfWaitingThreads() {
    return numberOfWaitingThreads;
  }

  /**
  *  Get the total number of connections handed out by the pool
  */
  public int getTotalConnectionsHandedOut() {
    return totalConnectionsHandedOut;
  }


  /**
  *  Get a string representation for the connection status/behaviour
  */
  public static String getStringStatus(int i) {
    if (i == CONNECTION_ACTIVE) {
      return "CONNECTION_ACTIVE";
    } else if (i == CONNECTION_INACTIVE) {
      return "CONNECTION_INACTIVE";
    } else if (i == CONNECTION_DUMPED) {
      return "CONNECTION_DUMPED";
    } else if (i == ON_CLOSE_SHOULD_DIE) {
      return "ON_CLOSE_SHOULD_DIE";
    } else if (i == ON_CLOSE_SHOULD_REUSE) {
      return "ON_CLOSE_SHOULD_REUSE";
    } else if (i == UNKNOWN_STATUS_CODE) {
      return "UNKNOWN_STATUS_CODE";
    }

    return "UNKNOWN_STATUS_CODE";
  }

  /**
  *  Get the current number of free connections
  */
  public int numberOfFreeConnections() {
    logger.verbose("START");
    int n = 0;
    for (ConnectionHolder ch : connections) {
      if (ch.status == CONNECTION_INACTIVE) {
        logger.verbose("INACTIVE");
        n++;
      }
    }
    return n;
  }

  /**
  *  Get the current number of active connections
  */
  public int numberOfActiveConnections() {
    int n = 0;
    for (ConnectionHolder ch : connections) {
      if (ch.status == CONNECTION_ACTIVE) {
        n++;
      }
    }
    return n;
  }

  /**
  *   Sets the default level for connection's isolation transaction level.
  *  This can only be set on startup - not during runtime.
  */
  protected void setInternalConnectionTransactionIsolation(String sConnectionTransactionIsolation) {
    // If not specified in the config file, then use the driver's default
    if (sConnectionTransactionIsolation == null) {
      try {
        Connection c = Util.getConnection(driverClass, driverURL, user, password);
        // if the connection is null, then it means the db is down or not reachable
        // so don't go any further.
        // If this is the case, the when the db comes back up
        // the transaction isolation level will -1, and the next 'get' on the Pool
        // will cause this code to be run again to default the level if needs be.
        if (c == null) {
          logger.warn("[Pool@" +poolName +"] setConnectionTransactionIsolation() : DB is down/not reachable, and because the pool config variable 'connectionTransactionLevel' is not set, it will be set when the db comes back up and the next call for a connection is made.");
          iConnectionTransactionIsolation = -1;
          return;
        }
        iConnectionTransactionIsolation = c.getTransactionIsolation();
        c.close();
      } catch (Throwable t) {

        logger.printStackTrace(t);
      }
    } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_NONE")) {
      iConnectionTransactionIsolation = Connection.TRANSACTION_NONE;
    } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_READ_COMMITTED")) {
      iConnectionTransactionIsolation = Connection.TRANSACTION_READ_COMMITTED;
    } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_READ_UNCOMMITTED")) {
      iConnectionTransactionIsolation = Connection.TRANSACTION_READ_UNCOMMITTED;
    } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_REPEATABLE_READ")) {
      iConnectionTransactionIsolation = Connection.TRANSACTION_REPEATABLE_READ;
    } else if (sConnectionTransactionIsolation.equalsIgnoreCase("TRANSACTION_SERIALIZABLE")) {
      iConnectionTransactionIsolation = Connection.TRANSACTION_SERIALIZABLE;
    // If not recognized, then use the driver's default
    } else {
      logger.warn("[Pool@" +poolName +"] setConnectionTransactionIsolation() : Do not recognize transaction level of '" +sConnectionTransactionIsolation +"', using driver default");
      try {
        Connection c = Util.getConnection(driverClass, driverURL, user, password);
        iConnectionTransactionIsolation = c.getTransactionIsolation();
        c.close();
      } catch (Throwable t) {

        logger.printStackTrace(t);
      }
    }

    logger.verbose("[Pool@" +poolName +"] setConnectionTransactionIsolation() : Set connection transaction level to '" +getInternalConnectionTransactionIsolation() +"'");

  }

  /**
  *   Gets the default level for connection's isolation transaction level.
  */
  protected String getInternalConnectionTransactionIsolation() {
    return getInternalConnectionTransactionIsolation(iConnectionTransactionIsolation);
  }

  /**
  *   Gets the default level for connection's isolation transaction level.
  */
  protected String getInternalConnectionTransactionIsolation(int level) {
    String sLevel = "DRIVER_DEFAULT";

    switch (level) {
      case Connection.TRANSACTION_NONE :
        sLevel = "TRANSACTION_NONE";
        break;
      case Connection.TRANSACTION_READ_COMMITTED :
        sLevel = "TRANSACTION_READ_COMMITTED";
        break;
      case Connection.TRANSACTION_READ_UNCOMMITTED :
        sLevel = "TRANSACTION_READ_UNCOMMITTED";
        break;
      case Connection.TRANSACTION_REPEATABLE_READ :
        sLevel = "TRANSACTION_REPEATABLE_READ";
        break;
      case Connection.TRANSACTION_SERIALIZABLE :
        sLevel = "TRANSACTION_SERIALIZABLE";
        break;
    }

    return sLevel;
  }




}
java2s.com  | Contact Us | Privacy Policy
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.