📄 connectionpool.java
字号:
/* * @(#) ConnectionPool 1.0 02/08/01 */package org.smartlib.pool.core;import org.apache.log4j.Logger;import java.util.*;import java.sql.*;/** * This class implements the Pool interface and thus is responsible for * managing a single pool of connections. */public class ConnectionPool implements Pool , PoolMonitor { private PoolConfig config; private final String name; private final Debugger debug; private int currentPoolSize = 0; private int usedConnections = 0; private Vector connectionList; private Vector connectionListenerList; private Thread pollerThread; private ConnectionProvider connProvider = null; private String validatorQuery = null; private volatile boolean shutDown = false; private Hashtable connectionHash = new Hashtable(); Logger logger = Logger.getLogger(ConnectionPool.class); /** * This method draws a raw connection from the database. */ private Connection loadConnection() throws ConnectionPoolException { try { Class.forName(config.getDriver()); } catch(ClassNotFoundException classNotFound) { throw new ConnectionPoolException("Could not load Driver", classNotFound); } Connection con = null; try { con = DriverManager.getConnection(config.getConnectionStringByName(name).getConnectString(), config.getUserName(), config.getPassword()); } catch (Exception e ) { throw new ConnectionPoolException("Could not obtain Connection", e); } currentPoolSize++; return con; } /** * @return Vector of connections in use. */ public Vector getConnectionsInUse() { return connectionList; } /** * @return Vector of registered ConnectionLeakListeners. */ public Vector getConnectionLeakListeners() { return connectionListenerList; } /** * @return Number of free connections in the pool. */ public int getNoOfFreeConnections() { return (currentPoolSize - usedConnections); } /** * This method returns an instance of ConfigMonitor. * @return ConfigMonitor for monitoring the configuration of the pool at * runtime. */ public ConfigMonitor getConfigMonitor() { return (ConfigMonitor)config; } public String getName() { return name; } /** * This method draws the initial raw connections. */ private void initialiseConnections() throws ConnectionPoolException { try { int minConnections = config.getMinConnections(); for (int i = 0 ; i<minConnections ; i++) { connectionHash.put(loadConnection(), Boolean.TRUE); } } catch (Exception e) { throw new ConnectionPoolException("Could not load initial connection" , e); } } /* * This method is called when the existing connection is wrapped to another * pool. */ private void returnConnectionToOtherPool(Connection conn) throws Exception { connProvider.returnConnection(conn); } /** * Constructor initialises the pool as per the configuration specified by * <code>config</code> */ ConnectionPool(PoolConfig config, String name) throws ConnectionPoolException { this.name = name; this.config = config; try { if (config.getConnectionLoaderClass() != null) connProvider = (ConnectionProvider)getClass().getClassLoader() .loadClass(config.getConnectionLoaderClassByName(name).getConnectionLoaderClass()).newInstance(); } catch (Exception exp) { throw new ConnectionPoolException("Error loading Connection Loader Class",exp); } if (connProvider == null) initialiseConnections(); debug = new Debugger(name, true); connectionList = new Vector(config.getMinConnections() , config.getIncrement()); connectionListenerList = new Vector(); try { if ( config.getDefaultListener() != null ) { String defaultListener = config.getDefaultListener(); addConnectionLeakListener((ConnectionLeakListener)getClass().getClassLoader().loadClass(defaultListener).newInstance()); } } catch (Exception e ) { throw new ConnectionPoolException("Could not load class " + config.getDefaultListener() , e); } if (config.isDetectLeaks()) { pollerThread = new Thread(new ConnectionLeakPollThread( connectionList , connectionListenerList , name, config.getPollThreadTime() , config.getLeakTimeOut(), this)); pollerThread.start(); } validatorQuery = config.getValidatorQuery(); } /** * This method returns the current size of the pool. * @return Current size of the pool. */ public int getCurrentPoolSize() { return currentPoolSize; } /** * This method returns a Connection from the connection pool. * The owner of this pool is marked as N/A indicating unknown/anonymous. * * <b>Note: This method blocks if the pool size has reached it's * maximum size and no free connections are available * until a free connection is available.</b> The time period for which this * method blocks depends on the connection-wait-time-out specified in * the configuration file. * * * @return Connection from the pool. * @exception ConnectionPoolException if there is any problem * getting connection. */ public Connection getConnection() throws ConnectionPoolException { if (config.isAllowAnonymousConnections()) return getConnection("N/A"); else throw new ConnectionPoolException ("You are not allowed to take anonumous connections, please provide an owner name"); } // Checks if the Connection is valid private boolean checkIfValid(Connection conn) { try { debug.print(" Checking Connection for '" + validatorQuery + "'"); if (validatorQuery != null && !validatorQuery.trim().equals("")) { Statement stmt = conn.createStatement(); boolean bool = stmt.execute(validatorQuery); stmt.close(); return bool; } else { return true; } } catch (SQLException exp) { if (logger.isDebugEnabled()) { logger.debug("Exception occurred while trying to test connection validity", exp); } return false; } } /* * This method is called when the existing connection is wrapped to another * pool. */ private Connection getConnectionFromOtherPool(String owner) throws ConnectionPoolException { try { synchronized (this) { if (config.getMaxConnections() == usedConnections) { try { debug.print("Hey the value is " + config.getConnectionWaitTimeOut()); wait(config.getConnectionWaitTimeOut()); if (config.getMaxConnections() == usedConnections) { throw new TimeOutException("Timed-out while " + "waiting for free connection"); } } catch (InterruptedException ie) { } } Connection conn = connProvider.getConnection(); usedConnections++; currentPoolSize++; // Checking if the connection is still live and active // if not get replace the old one with new one if (checkIfValid(conn)) { SmartConnection smt = new SmartConnection(conn, this,owner, config.isAutoClose()); connectionList.add(smt); return smt; } else { boolean valid = false; int i=1; while (!valid) { conn = connProvider.getConnection(); valid = checkIfValid(conn); i++; if (i == 3 && !valid) throw new ConnectionPoolException("Three consecutive cnnections failes the Validator Query org.smartlib.pool.test"); } SmartConnection smt = new SmartConnection(conn, this,owner, config.isAutoClose());
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -