Your own connection pool : Connection Pool « Database SQL JDBC « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Class
8. Collections Data Structure
9. Data Type
10. Database SQL JDBC
11. Design Pattern
12. Development Class
13. EJB3
14. Email
15. Event
16. File Input Output
17. Game
18. Generics
19. GWT
20. Hibernate
21. I18N
22. J2EE
23. J2ME
24. JDK 6
25. JNDI LDAP
26. JPA
27. JSP
28. JSTL
29. Language Basics
30. Network Protocol
31. PDF RTF
32. Reflection
33. Regular Expressions
34. Scripting
35. Security
36. Servlets
37. Spring
38. Swing Components
39. Swing JFC
40. SWT JFace Eclipse
41. Threads
42. Tiny Application
43. Velocity
44. Web Services SOA
45. XML
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java » Database SQL JDBC » Connection PoolScreenshots 
Your own connection pool
  
/*
 * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
 *
 * Licensed under the Aduna BSD-style license.
 */

import java.sql.Array;
import java.sql.Blob;
import java.sql.CallableStatement;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.DriverManager;
import java.sql.NClob;
import java.sql.PreparedStatement;
import java.sql.SQLClientInfoException;
import java.sql.SQLException;
import java.sql.SQLWarning;
import java.sql.SQLXML;
import java.sql.Savepoint;
import java.sql.Statement;
import java.sql.Struct;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

public class ConnectionPool {

/*--------------------------------------------------+
| Variables                                         |
+--------------------------------------------------*/

  protected List<PoolConnection> _connections;

  protected String _url;
  protected String _user;
  protected String _password;

  /**
   * Indicates whether the ConnectionPool should check the status of
   * connections (closed, has warnings) before they are returned.
   **/
  protected boolean _checkConnections = true;

  protected long _cleaningInterval =  30 1000// 30 seconds
  protected long _maxIdleTime = 30 1000// 30 seconds

  protected long _maxUseTime = -1// disabled by default

  protected boolean _draining = false;

  protected PoolCleaner _cleaner;

/*--------------------------------------------------+
| Constructors                                      |
+--------------------------------------------------*/

  public ConnectionPool(String url, String user, String password) {
    _url = url;
    _user = user;
    _password = password;

    _connections = new ArrayList<PoolConnection>();
  }

  /**
   * Sets the flag that determines whether the the status of connections
   * (closed, has warnings) is checked before they are returned by
   * getConnection(). With some jdbc-drivers, the extra checks can have
   * a large performance penalty. Default value is 'true'.
   **/
  public void setCheckConnections(boolean checkConnections) {
    _checkConnections = checkConnections;
  }

  /**
   * Sets the interval for the pool cleaner to come into action. The pool
   * cleaner checks the connection pool every so many milliseconds for
   * connections that should be removed. The default interval is 30 seconds.
   @param cleaningInterval The interval in milliseconds.
   **/
  public void setCleaningInterval(long cleaningInterval) {
    _cleaningInterval = cleaningInterval;
  }

  /**
   * Sets the maximum time that a connection is allowed to be idle. A
   * connection that has been idle for a longer time will be removed
   * by the pool cleaner the next time it check the pool. The default
   * value is 30 seconds.
   *
   @param maxIdleTime The maximum idle time in milliseconds.
   **/
  public void setMaxIdleTime(long maxIdleTime) {
    _maxIdleTime = maxIdleTime;
  }

  /**
   * Sets the maximum time that a connection is allowed to be used. A
   * connection that has been used for a longer time will be forced to
   * close itself, even if it is still in use. Normally, this time should
   * only be reached in case an program "forgets" to close a connection.
   * The maximum time is switched of by default.
   *
   @param maxUseTime The maximum time a connection can be used in
   * milliseconds, or a negative value if there is no maximum.
   **/
  public void setMaxUseTime(long maxUseTime) {
    _maxUseTime = maxUseTime;
  }

/*--------------------------------------------------+
| Methods                                           |
+--------------------------------------------------*/

  public Connection getConnection()
    throws SQLException
  {
    if (_draining) {
      throw new SQLException("ConnectionPool was drained.");
    }

    // Try reusing an existing Connection
    synchronized (_connections) {
      PoolConnection pc = null;

      for (int i = 0; i < _connections.size(); i++) {
        pc = _connections.get(i);

        if (pc.lease()) {
          // PoolConnection is available

          if (!_checkConnections) {
            return pc;
          }
          else {
            // Check the status of the connection
            boolean isHealthy = true;

            try {
              if (pc.isClosed() && pc.getWarnings() != null) {
                // If something happend to the connection, we
                // don't want to use it anymore.
                isHealthy = false;
              }
            }
            catch(SQLException sqle) {
              // If we can't even ask for that information, we
              // certainly don't want to use it anymore.
              isHealthy = false;
            }

            if (isHealthy) {
              return pc;
            }
            else {
              try {
                pc.expire();
              }
              catch(SQLException sqle) {
                // ignore
              }
              _connections.remove(i);
            }
          }
        }
      }
    }

    // Create a new Connection
    Connection con = DriverManager.getConnection(_url, _user, _password);
    PoolConnection pc = new PoolConnection(con);
    pc.lease();

    // Add it to the pool
    synchronized (_connections) {
      _connections.add(pc);

      if (_cleaner == null) {
        // Put a new PoolCleaner to work
        _cleaner = new PoolCleaner(_cleaningInterval);
        _cleaner.start();
      }
    }

    return pc;
  }

  public void removeExpired() {
    PoolConnection pc;

    long maxIdleDeadline = System.currentTimeMillis() - _maxIdleTime;
    long maxUseDeadline = System.currentTimeMillis() - _maxUseTime;

    synchronized (_connections) {
      // Check all connections
      for (int i = _connections.size() 1; i >= 0; i--) {
        pc = _connections.get(i);

        if (!pc.inUse() && pc.getTimeClosed() < maxIdleDeadline) {
          // Connection has been idle too long, close it.
          _connections.remove(i);
          try {
            pc.expire();
          }
          catch (SQLException ignore) {
          }
        }
        else if (
          _maxUseTime >= && // don't check if disabled
          pc.inUse() &&
          pc.getTimeOpened() < maxUseDeadline)
        {
          // Connection has been used too long, close it.

          // Print the location where the connetion was acquired
          // as it probably forgot to close the connection (which
          // is a bug).
          System.err.println("Warning: forced closing of a connection that has been in use too long.");
          System.err.println("Connection was acquired in:");
          pc.printStackTrace();
          System.err.println();

          _connections.remove(i);
          try {
            pc.expire();
          }
          catch (SQLException ignore) {
          }
        }
      }

      // Stop the PoolCleaner if the pool is empty.
      if (_connections.size() == && _cleaner != null) {
        _cleaner.halt();
        _cleaner = null;
      }
    }
  }

  public int getPoolSize() {
    synchronized (_connections) {
      return _connections.size();
    }
  }

  /**
   * Drains the pool. After the ConnectionPool has been drained it will not
   * give out any more connections and all existing connections will be
   * closed. This action cannot be reversed, so a ConnectionPool will become
   * unusable once it has been drained.
   **/
  public void drain() {
    _draining = true;

    if (_cleaner != null) {
      _cleaner.halt();
    }

    synchronized (_connections) {
      for (int i = _connections.size() 1; i >= 0; i--) {
        PoolConnection pc = _connections.get(i);

        if (pc.inUse()) {
          System.err.println("Warning: forced closing of a connection still in use.");
          System.err.println("Connection was acquired in:");
          pc.printStackTrace();
          System.err.println();
        }

        _connections.remove(i);
        try {
          pc.expire();
        }
        catch (SQLException ignore) {
        }
      }
    }
  }

  protected void finalize() {
    drain();
  }

/*--------------------------------------------+
| inner class PoolConnection                  |
+--------------------------------------------*/

  /**
   * Wrapper around java.sql.Connection
   **/
  static class PoolConnection implements Connection {

  /*----------------------------------+
  | Variables                         |
  +----------------------------------*/

    protected Connection _conn;

    protected boolean _inUse;

    protected boolean _autoCommit;

    /** Time stamp for the last time the connection was opened. **/
    protected long _timeOpened;

    /** Time stamp for the last time the connection was closed. **/
    protected long _timeClosed;

    private Throwable _throwable;

  /*----------------------------------+
  | Constructors                      |
  +----------------------------------*/

    public PoolConnection(Connection conn) {
      _conn = conn;
      _inUse = false;
      _autoCommit = true;
    }

  /*----------------------------------+
  | PoolConnection specific methods   |
  +----------------------------------*/

    /**
     * Tries to lease this connection. If the attempt was successful (the
     * connection was available), a flag will be set marking this connection
     * "in use", and this method will return 'true'. If the connection was
     * already in use, this method will return 'false'.
     **/
    public synchronized boolean lease() {
      if (_inUse) {
        return false;
      }
      else {
        _inUse = true;
        _timeOpened = System.currentTimeMillis();
        return true;
      }
    }

    /**
     * Checks if the connection currently is used by someone.
     **/
    public boolean inUse() {
      return _inUse;
    }

    /**
     * Returns the time stamp of the last time this connection was
     * opened/leased.
     **/
    public synchronized long getTimeOpened() {
      return _timeOpened;
    }

    /**
     * Returns the time stamp of the last time this connection was
     * closed.
     **/
    public synchronized long getTimeClosed() {
      return _timeClosed;
    }

    /**
     * Expires this connection and closes the underlying connection to the
     * database. Once expired, a connection can no longer be used.
     **/
    public void expire()
      throws SQLException
    {
      _conn.close();
      _conn = null;
    }

    public void printStackTrace() {
      _throwable.printStackTrace(System.err);
    }

  /*----------------------------------+
  | Wrapping methods for Connection   |
  +----------------------------------*/

    public synchronized void close()
      throws SQLException
    {
      // Multiple calls to close?
      if (_inUse) {
        _timeClosed = System.currentTimeMillis();
        _inUse = false;

        if (_autoCommit == false) {
          // autoCommit has been set to false by this user,
          // restore the default "autoCommit = true"
          setAutoCommit(true);
        }
      }
    }

    public Statement createStatement()
      throws SQLException
    {
      _throwable = new Throwable();
      return _conn.createStatement();
    }

    public PreparedStatement prepareStatement(String sql)
      throws SQLException
    {
      _throwable = new Throwable();
      return _conn.prepareStatement(sql);
    }

    public CallableStatement prepareCall(String sql)
      throws SQLException
    {
      return _conn.prepareCall(sql);
    }

    public String nativeSQL(String sql)
      throws SQLException
    {
      return _conn.nativeSQL(sql);
    }

    public void setAutoCommit(boolean autoCommit)
      throws SQLException
    {
      _conn.setAutoCommit(autoCommit);
      _autoCommit = _conn.getAutoCommit();
    }

    public boolean getAutoCommit()
      throws SQLException
    {
      return _conn.getAutoCommit();
    }

    public void commit()
      throws SQLException
    {
      _conn.commit();
    }

    public void rollback()
      throws SQLException
    {
      _conn.rollback();
    }

    public boolean isClosed()
      throws SQLException
    {
      return _conn.isClosed();
    }

    public DatabaseMetaData getMetaData()
      throws SQLException
    {
      return _conn.getMetaData();
    }

    public void setReadOnly(boolean readOnly)
      throws SQLException
    {
      _conn.setReadOnly(readOnly);
    }

    public boolean isReadOnly()
      throws SQLException
    {
      return _conn.isReadOnly();
    }

    public void setCatalog(String catalog)
      throws SQLException
    {
      _conn.setCatalog(catalog);
    }

    public String getCatalog()
      throws SQLException
    {
      return _conn.getCatalog();
    }

    public void setTransactionIsolation(int level)
      throws SQLException
    {
      _conn.setTransactionIsolation(level);
    }

    public int getTransactionIsolation()
      throws SQLException
    {
      return _conn.getTransactionIsolation();
    }

    public SQLWarning getWarnings()
      throws SQLException
    {
      return _conn.getWarnings();
    }

    public void clearWarnings()
      throws SQLException
    {
      _conn.clearWarnings();
    }

    public Statement createStatement(
      int resultSetType, int resultSetConcurrency)
      throws SQLException
    {
      return _conn.createStatement(resultSetType, resultSetConcurrency);
    }

    public PreparedStatement prepareStatement(
      String sql, int resultSetType, int resultSetConcurrency)
      throws SQLException
    {
      return _conn.prepareStatement(sql, resultSetType, resultSetConcurrency);
    }

    public CallableStatement prepareCall(
      String sql, int resultSetType, int resultSetConcurrency)
      throws SQLException
    {
      return _conn.prepareCall(sql, resultSetType, resultSetConcurrency);
    }

    public Map<String,Class<?>> getTypeMap()
      throws SQLException
    {
      return _conn.getTypeMap();
    }

    public void setTypeMap(Map<String,Class<?>> map)
      throws SQLException
    {
      _conn.setTypeMap(map);
    }

/*
 * The following methods are new methods from java.sql.Connection that
 * were added in JDK1.4. These additions are incompatible with older JDK
 * versions.
 */

    public void setHoldability(int holdability)
      throws SQLException
    {
      _conn.setHoldability(holdability);
    }

    public int getHoldability()
      throws SQLException
    {
      return _conn.getHoldability();
    }

    public Savepoint setSavepoint()
      throws SQLException
    {
      return _conn.setSavepoint();
    }

    public Savepoint setSavepoint(String name)
      throws SQLException
    {
      return _conn.setSavepoint(name);
    }

    public void rollback(Savepoint savepoint)
      throws SQLException
    {
      _conn.rollback(savepoint);
    }

    public void releaseSavepoint(Savepoint savepoint)
      throws SQLException
    {
      _conn.releaseSavepoint(savepoint);
    }

    public Statement createStatement(
        int resultSetType,
        int resultSetConcurrency,
        int resultSetHoldability)
      throws SQLException
    {
      return _conn.createStatement(
        resultSetType, resultSetConcurrency, resultSetHoldability);
    }

    public PreparedStatement prepareStatement(
        String sql,
        int resultSetType,
        int resultSetConcurrency,
        int resultSetHoldability)
      throws SQLException
    {
      return _conn.prepareStatement(
        sql, resultSetType, resultSetConcurrency, resultSetHoldability);
    }

    public CallableStatement prepareCall(
        String sql,
        int resultSetType,
        int resultSetConcurrency,
        int resultSetHoldability)
      throws SQLException
    {
      return _conn.prepareCall(
        sql, resultSetType, resultSetConcurrency, resultSetHoldability);
    }

    public PreparedStatement prepareStatement(
        String sql, int autoGenerateKeys)
      throws SQLException
    {
      return _conn.prepareStatement(sql, autoGenerateKeys);
    }

    public PreparedStatement prepareStatement(
        String sql, int[] columnIndexes)
      throws SQLException
    {
      return _conn.prepareStatement(sql, columnIndexes);
    }

    public PreparedStatement prepareStatement(
        String sql, String[] columnNames)
      throws SQLException
    {
      return _conn.prepareStatement(sql, columnNames);
    }

    public Clob createClob() throws SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public Blob createBlob() throws SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public NClob createNClob() throws SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public SQLXML createSQLXML() throws SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public boolean isValid(int timeoutthrows SQLException {
      // TODO Auto-generated method stub
      return false;
    }

    public void setClientInfo(String name, String valuethrows SQLClientInfoException {
      // TODO Auto-generated method stub
      
    }

    public void setClientInfo(Properties propertiesthrows SQLClientInfoException {
      // TODO Auto-generated method stub
      
    }

    public String getClientInfo(String namethrows SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public Properties getClientInfo() throws SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public Array createArrayOf(String typeName, Object[] elementsthrows SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public Struct createStruct(String typeName, Object[] attributesthrows SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public <T> T unwrap(Class<T> ifacethrows SQLException {
      // TODO Auto-generated method stub
      return null;
    }

    public boolean isWrapperFor(Class<?> ifacethrows SQLException {
      // TODO Auto-generated method stub
      return false;
    }
  }

/*--------------------------------------------+
| inner class PoolCleaner                     |
+--------------------------------------------*/

  class PoolCleaner extends Thread {

    protected long _cleaningInterval;
    protected boolean _mustStop;

    public PoolCleaner(long cleaningInterval) {
      if (cleaningInterval < 0) {
        throw new IllegalArgumentException("cleaningInterval must be >= 0");
      }
      _mustStop = false;
      _cleaningInterval = cleaningInterval;

      setDaemon(true);
    }

    public void run() {
      while (!_mustStop) {
        try {
          sleep(_cleaningInterval);
        }
        catch (InterruptedException ignore) {
        }

        if (_mustStop) {
          break;
        }

        removeExpired();
      }
    }

    public void halt() {
      _mustStop = true;
      synchronized (this) {
        this.interrupt();
      }
    }
  }
}

   
    
  
Related examples in the same category
1. Pooled Connection Example
2. Mini Connection Pool Manager
3. A common intermediate format for a non-XA JDBC pool
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.