精华区 [关闭][返回]

当前位置:网易精华区>>讨论区精华>>编程开发>>● Java>>临时目录>>Re:关于连接池!请哪位老兄给我上一课!!

主题:Re:关于连接池!请哪位老兄给我上一课!!
发信人: huanghwh(五云人)
整理人: zjxyz(2003-02-23 14:59:14), 站内信件
【 在 liuzhenai 的大作中提到:】
:
:连接池,可以提高JSP程序的效率,jsp使用连接池是很有必要的,但是兄弟我对连接池还知之甚少,请哪位老兄用精简、通俗的语言给我补一课,谢谢!!
:
:1、从本质上讲,连接池到底有什么作用(主要结合jsp,mssql/oracle)?
:2、从形式上讲,连接池的使用,需要掌哪几个类?(最好举个例,这样会清楚很多)
:
:......
part two

   /**
    * <p>Loads the given configuration file.  All global
    * properties (such as JDBCDriver) will be
    * read and removed from the properties list. Any leftover
    * properties will be returned. Returns null if the
    * properties could not be loaded
    *
    * @param name Configuration file name
    * @return true if the configuration file was loaded
    */
  private boolean loadConfig(String name)
    throws Exception
    {
      boolean rc = false;

      // Get our class loader
      ClassLoader cl = getClass().getClassLoader();

      // Attempt to open an input stream to the configuration file.
      // The configuration file is considered to be a system
      // resource.
      java.io.InputStream in;

      if (cl != null) {
        in = cl.getResourceAsStream(name);
      }
      else {
        in = ClassLoader.getSystemResourceAsStream(name);
      }

      if (in == null) { //use normal FileInpustream
        in = new FileInputStream(name);
      }

      // If the input stream is null, then the configuration file
      // was not found
      if(in == null)
        throw new Exception("ConnectionPool configuration file '" +
                           name + "' not found");
      else {
        try {
          m_JDBCProperties = new java.util.Properties();
          java.util.Properties allProperties = new java.util.Properties();
          allProperties.load(in);
          // Load the configuration file into the properties table
          //m_JDBCProperties.load(in);

          //fill m_JDBCProperties
          m_JDBCProperties.put("JDBCDriver", allProperties.getProperty("JDBCDriver"));
          m_JDBCProperties.put("JDBCConnectionURL", allProperties.getProperty("JDBCConnectionURL"));
          m_JDBCProperties.put("ConnectionPoolSize", allProperties.getProperty("ConnectionPoolSize"));
          m_JDBCProperties.put("ConnectionPoolMax", allProperties.getProperty("ConnectionPoolMax"));
          m_JDBCProperties.put("ConnectionTimeout", allProperties.getProperty("ConnectionTimeout"));
          m_JDBCProperties.put("ConnectionUseCount", allProperties.getProperty("ConnectionUseCount"));
          m_JDBCProperties.put("User", allProperties.getProperty("User"));
          m_JDBCProperties.put("Password", allProperties.getProperty("Password"));
          allProperties.clear();

          // Got the properties. Pull out the properties that we
          // are interested in
          m_JDBCDriver = consume(m_JDBCProperties, "JDBCDriver");
          m_JDBCConnectionURL = consume(m_JDBCProperties,
                                        "JDBCConnectionURL");
          m_ConnectionPoolSize = consumeInt(m_JDBCProperties,
                                            "ConnectionPoolSize");
          m_ConnectionPoolMax = consumeInt(m_JDBCProperties,
                                           "ConnectionPoolMax");
          m_ConnectionTimeout = consumeInt(m_JDBCProperties,
                                           "ConnectionTimeout");
          m_ConnectionUseCount = consumeInt(m_JDBCProperties,
                                            "ConnectionUseCount");
          rc = true;
        }
        finally {
          // Always close the input stream
          if (in != null) {
            try {
              in.close();
            }
            catch (Exception ex) {
            }
          }
        }
      }
      return rc;
    }

  /**
    * <p>Consumes the given property and returns the value.
    *
    * @param properties Properties table
    * @param key Key of the property to retrieve and remove from
    * the properties table
    * @return Value of the property, or null if not found
    */
  private String consume(java.util.Properties p, String key)
    {
      String s = null;

      if ((p != null) &&
          (key != null)) {

        // Get the value of the key
        s = p.getProperty(key);

        // If found, remove it from the properties table
        if (s != null) {
          p.remove(key);
        }
      }
      return s;
    }

  /**
    * <p>Consumes the given property and returns the integer
    * value.
    *
    * @param properties Properties table
    * @param key Key of the property to retrieve and remove from
    * the properties table
    * @return Value of the property, or -1 if not found
    */
  private int consumeInt(java.util.Properties p, String key)
    {
      int n = -1;

      // Get the String value
      String value = consume(p, key);

      // Got a value; convert to an integer
      if (value != null) {
        try {
          n = Integer.parseInt(value);
        }
        catch (Exception ex) {
        }
      }
      return n;
    }

  /**
    * <p>Creates the initial connection pool. A timer thread
    * is also created so that connection timeouts can be
    * handled.
    *
    * @return true if the pool was created
    */
  private void createPool() throws Exception
    {
      // Sanity check our properties
      if (m_JDBCDriver == null) {
        throw new Exception("JDBCDriver property not found");
      }
      if (m_JDBCConnectionURL == null) {
        throw new Exception("JDBCConnectionURL property not found");
      }
      if (m_ConnectionPoolSize < 0) {
throw new Exception("ConnectionPoolSize property not found");
}
if (m_ConnectionPoolSize == 0) {
throw new Exception("ConnectionPoolSize invalid");
}
if (m_ConnectionPoolMax < m_ConnectionPoolSize) {
trace("WARNING - ConnectionPoolMax is invalid and will " +
"be ignored");
m_ConnectionPoolMax = -1;
}
if (m_ConnectionTimeout < 0) {
// Set the default to 30 minutes
m_ConnectionTimeout = 30;
}

// Dump the parameters we are going to use for the pool.
// We don't know what type of servlet environment we will
// be running in - this may go to the console or it
// may be redirected to a log file
//trace("JDBCDriver = " + m_JDBCDriver);
//trace("JDBCConnectionURL = " + m_JDBCConnectionURL);
//trace("ConnectionPoolSize = " + m_ConnectionPoolSize);
//trace("ConnectionPoolMax = " + m_ConnectionPoolMax);
//trace("ConnectionUseCount = " + m_ConnectionUseCount);
//trace("ConnectionTimeout = " + m_ConnectionTimeout +
// " seconds");

// Also dump any additional JDBC properties
java.util.Enumeration enum = m_JDBCProperties.keys();
while (enum.hasMoreElements()) {
String key = (String) enum.nextElement();
String value = m_JDBCProperties.getProperty(key);
//trace("(JDBC Property) " + key + " = " + value);
}

// Attempt to create a new instance of the specified
// JDBC driver. Well behaved drivers will register
// themselves with the JDBC DriverManager when they
// are instantiated
//trace("Registering " + m_JDBCDriver);
java.sql.Driver d = (java.sql.Driver)
Class.forName(m_JDBCDriver).newInstance();

// Create the vector for the pool
m_pool = new java.util.Vector();

// Bring the pool to the minimum size
fillPool(m_ConnectionPoolSize);
}

/**
* <p>Adds a new connection to the pool
    *
    * @return Index of the new pool entry, or -1 if an
    * error has occurred
    */
  private int addConnection()
    {
      int index = -1;

      try {
        // Calculate the new size of the pool
        int size = m_pool.size() + 1;

        // Create a new entry
        fillPool(size);

        // Set the index pointer to the new connection if one
        // was created
        if (size == m_pool.size()) {
          index = size - 1;
        }
      }
      catch (Exception ex) {
        ex.printStackTrace();
      }
      return index;
    }

  /**
    * <p>Brings the pool to the given size
    */
  private synchronized void fillPool(int size) throws Exception
    {
      boolean useProperties = true;
      String userID = null;
      String password = null;

      // If the only properties present are the user id and
      // password, get the connection using them instead of
      // the properties object
      if (m_JDBCProperties != null) {

        // Make sure there are only 2 properties, and they are
        // the user id and password
        if (m_JDBCProperties.size() == 2) {
          userID =
            getPropertyIgnoreCase(m_JDBCProperties, "user");
          password =
            getPropertyIgnoreCase(m_JDBCProperties, "password");

          // If all we've got is a user id and password then
          // don't use the properties
          if ((userID != null) && (password != null)) {
            useProperties = false;
          }
        }

      }

      // Loop while we need to create more connections
      while (m_pool.size() < size) {

ConnectionObject co = new ConnectionObject();

// Create the connection
if (useProperties) {
co.con = DriverManager.getConnection(m_JDBCConnectionURL,
m_JDBCProperties);
}
else {
co.con = DriverManager.getConnection(m_JDBCConnectionURL,
userID, password);
}

// Do some sanity checking on the first connection in
// the pool
if (m_pool.size() == 0) {

// Get the maximum number of simultaneous connections
// as reported by the JDBC driver
java.sql.DatabaseMetaData md = co.con.getMetaData();
m_MaxConnections = md.getMaxConnections();
}

// Give a warning if the size of the pool will exceed
// the maximum number of connections allowed by the
// JDBC driver
if ((m_MaxConnections > 0) &&
            (size > m_MaxConnections)) {
          trace("WARNING: Size of pool will exceed safe maximum of " +
                m_MaxConnections);
        }

        // Clear the in use flag
        co.inUse = false;

        // Set the last access time
        touch(co);

        m_pool.addElement(co);
      }
    }

  /**
   * Gets a the named propery, ignoring case. Returns null if
   * not found
   * @param p The property set
   * @param name The property name
   * @return The value of the propery, or null if not found
   */
  private String getPropertyIgnoreCase(java.util.Properties p,
                                       String name)
    {
      if ((p == null) || (name == null)) return null;

      String value = null;

      // Get an enumeration of the property names
      java.util.Enumeration enum = p.propertyNames();

      // Loop through the enum, looking for the given property name
      while (enum.hasMoreElements()) {
        String pName = (String) enum.nextElement();
        if (pName.equalsIgnoreCase(name)) {
          value = p.getProperty(pName);
          break;
        }
      }

      return value;
    }

  /**
    * <p>Find the given connection in the pool
    *
    * @return Index into the pool, or -1 if not found
    */
  private int find(java.sql.Connection con)
    {
      int index = -1;

      // Find the matching Connection in the pool
      if ((con != null) &&
          (m_pool != null)) {
        for (int i = 0; i < m_pool.size(); i++) {
ConnectionObject co = (ConnectionObject)
m_pool.elementAt(i);
if (co.con == con) {
index = i;
break;
}
}
}
return index;
}

/**
* <p>Called by the timer each time a clock cycle expires.
    * This gives us the opportunity to timeout connections
    */
  public synchronized void TimerEvent(Object object)
    {
      // No pool means no work
      if (m_pool == null) {
        return;
      }

      // Get the current time in milliseconds
      long now = System.currentTimeMillis();

      // Check for any expired connections and remove them
      for (int i = m_pool.size() - 1; i >= 0; i--) {
        ConnectionObject co = (ConnectionObject)
          m_pool.elementAt(i);

        // If the connection is not in use and it has not been
        // used recently, remove it
        if (!co.inUse) {
          if ((m_ConnectionTimeout > 0) &&
              (co.lastAccess +
               (m_ConnectionTimeout * 1000) < now)) {
removeFromPool(i);
}
}
}

// Remove any connections that are no longer open
for (int i = m_pool.size() - 1; i >= 0; i--) {
        ConnectionObject co = (ConnectionObject)
          m_pool.elementAt(i);
        try {
          // If the connection is closed, remove it from the pool
          if (co.con.isClosed()) {
            //trace("Connection closed unexpectedly");
            removeFromPool(i);
          }
        }
        catch (Exception ex) {
        }
      }

      // Now ensure that the pool is still at it's minimum size
      try {
        if (m_pool != null) {
          if (m_pool.size() < m_ConnectionPoolSize) {
fillPool(m_ConnectionPoolSize);
}
}
}
catch (Exception ex) {
ex.printStackTrace();
}
}

/**
* <p>Sets the last access time for the given ConnectionObject
    */
  private void touch(ConnectionObject co)
    {
      if (co != null) {
        co.lastAccess = System.currentTimeMillis();
      }
    }

  /**
    * <p>Trace the given string
    */
  private void trace(String s)
    {
      System.out.println("ConnectionPool: " + s);
    }

  /**
   * just for test
   */
   public static void main(String[] args){
    System.out.println(System.getProperty("user.dir"));
    try {
      ConnectionPool cPool = new ConnectionPool();
      cPool.initialize("etc/ConnectionPool.cfg");
      java.sql.Connection con = cPool.getConnection();
      cPool.destroy();
    }
    catch(Exception ex) {
      ex.printStackTrace();
    }

  }
}

// This package-private class is used to represent a single
// connection object
class ConnectionObject
{
  // The JDBC Connection
  public java.sql.Connection con;

  // true if this connection is currently in use
  public boolean inUse;

  // The last time (in milliseconds) that this connection was used
  public long lastAccess;

  // The number of times this connection has been used
  public int useCount;

  /**
    * <p>Determine if the connection is available
    *
    * @return true if the connection can be used
    */
  public boolean isAvailable()
    {
      boolean available = false;

      try {

        // To be available, the connection cannot be in use
        // and must be open
        if (con != null) {
          if (!inUse &&
              !con.isClosed()) {
            available = true;
          }
        }
      }
      catch (Exception ex) {
      }

      return available;
    }

  /**
    * <p>Convert the object contents to a String
    */
  public String toString()
    {
      return "Connection=" + con.toString() + ",inUse=" + inUse +
        ",lastAccess=" + new Date(lastAccess) + ",useCount=" + useCount;
    }

}



----
Power OS is FreeBSD.
Network is computing.
Java is network language.
Web is Application.

[关闭][返回]