dbpoolimpl.java

来自「RESIN 3.2 最新源码」· Java 代码 · 共 1,116 行 · 第 1/2 页

JAVA
1,116
字号
/* * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source 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, or any warranty * of NON-INFRINGEMENT.  See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * *   Free Software Foundation, Inc. *   59 Temple Place, Suite 330 *   Boston, MA 02111-1307  USA * * @author Scott Ferguson */package com.caucho.sql;import com.caucho.config.ConfigException;import com.caucho.config.types.InitParam;import com.caucho.config.types.Period;import com.caucho.loader.Environment;import com.caucho.loader.EnvironmentClassLoader;import com.caucho.loader.EnvironmentListener;import com.caucho.log.Log;import com.caucho.util.Alarm;import com.caucho.util.AlarmListener;import com.caucho.util.L10N;import com.caucho.sql.spy.*;import javax.naming.InitialContext;import javax.naming.NamingException;import javax.resource.spi.ManagedConnectionFactory;import javax.sql.ConnectionPoolDataSource;import javax.sql.XADataSource;import javax.transaction.TransactionManager;import java.io.PrintWriter;import java.sql.Driver;import java.sql.SQLException;import java.util.ArrayList;import java.util.HashMap;import java.util.Iterator;import java.util.logging.Level;import java.util.logging.Logger;/** * Manages a pool of database connections.  In addition, DBPool configures * the database connection from a configuration file. * * <p>Like JDBC 2.0 pooling, DBPool returns a wrapped Connection. * Applications can use that connection just like an unpooled connection. * It is more important than ever to <code>close()</code> the connection, * because the close returns the connection to the connection pool. * * <h4>Example using DataSource JNDI style (recommended)</h4> * * <pre><code> * Context env = (Context) new InitialContext().lookup("java:comp/env"); * DataSource pool = (DataSource) env.lookup("jdbc/test"); * Connection conn = pool.getConnection(); * try { *   ... // normal connection stuff * } finally { *   conn.close(); * } * </code></pre> * * <h4>Configuration</h4> * * <pre><code> * &lt;database name='jdbc/test'> *   &lt;init> *     &lt;driver>postgresql.Driver&lt;/driver> *     &lt;url>jdbc:postgresql://localhost/test&lt;/url> *     &lt;user>ferg&lt;/user> *     &lt;password>foobar&lt;/password> *   &lt;/init> * &lt;/database> * </code></pre> * * <h4>Pool limits and timeouts</h4> * * The pool will only allow getMaxConnections() connections alive at a time. * If <code>getMaxConnection</code> connections are already active, * <code>getPooledConnection</code> will block waiting for an available * connection.  The wait is timed.  If connection-wait-time passes * and there is still no connection, <code>getPooledConnection</code> * create a new connection anyway. * * <p>Connections will only stay in the pool for about 5 seconds.  After * that they will be removed and closed.  This reduces the load on the DB * and also protects against the database dropping old connections. */public class DBPoolImpl implements AlarmListener, EnvironmentListener {  protected static final Logger log    = Logger.getLogger(DBPoolImpl.class.getName());  private static final L10N L = new L10N(DBPoolImpl.class);  /**   * The beginning of the URL used to connect to a database with   * this pooled connection driver.   */  private static final String URL_PREFIX = "jdbc:caucho:" ;  /**   * The key used to look into the properties passed to the   * connect method to find the username.   */  public static final String PROPERTY_USER = "user" ;  /**   * The key used to look into the properties passed to the   * connect method to find the password.   */  public static final String PROPERTY_PASSWORD = "password" ;  // How long an unused connection can remain in the pool  private static final long MAX_IDLE_TIME = 30000;  private String _name;  private ArrayList<DriverConfig> _driverList    = new ArrayList<DriverConfig>();  private ArrayList<DriverConfig> _backupDriverList    = new ArrayList<DriverConfig>();  private ConnectionConfig _connectionConfig    = new ConnectionConfig();  // private ManagedFactoryImpl _mcf;  private ManagedConnectionFactory _mcf;  private String _user;  private String _password;  // total connections allowed in this pool  private int _maxConnections = 128;  // time before an idle connection is closed  private long _maxIdleTime = MAX_IDLE_TIME;  // max time a connection is allowed to be active (6 hr)  private long _maxActiveTime = 6L * 3600L * 1000L;  // max time a connection is allowed in the pool  private long _maxPoolTime = 24L * 3600L * 1000L;  // how long to wait for a connection, say 10 minutes  private long _connectionWaitTime = 600 * 1000;  private int _connectionWaitCount = (int) (_connectionWaitTime / 1000);  // connections to create even when the max-connections overflows.  private int _maxOverflowConnections = 0;  // true if the pool has started  private boolean _isStarted;  // true if the pool has closed  private boolean _isClosed;  // if true, the pool can't be closed.  private boolean _forbidClose;  // The JDBC table to be used to ping for connection liveness.  private String _pingTable;  // The Query used for connection liveness.  private String _pingQuery;  // Ping when the connection is reused.  private Boolean _isPing;  // How long between pings  private long _pingInterval = 1000;  // True if the pool is transactional  private boolean _isTransactional = true;  // True if the pool should never allow isSameRM  private boolean _isXAForbidSameRM = false;  // The transaction manager if the pool participates in transactions.  private TransactionManager _tm;  // how long before the transaction times out  private long _transactionTimeout = 0;  private boolean _isSpy;  private SpyDataSource _spyDataSource;  private int _maxCloseStatements = 256;  // The prepared statement cache size.  private int _preparedStatementCacheSize = 0;  private boolean _isWrapStatements = true;    // The connections currently in the pool.  // transient ArrayList<PoolItem> _connections = new ArrayList<PoolItem>();  // Count for debugging ids.  private int _idCount;  // The alarm  private Alarm _alarm;  /**   * Null constructor for the Driver interface; called by the JNDI   * configuration.  Applications should not call this directly.   */  public DBPoolImpl()  {  }  /**   * Returns the Pool's name   */  public String getName()  {    return _name;  }  /**   * Sets the Pool's name.  Also puts the pool in the classloader's   * list of pools.   */  public void setName(String name)  {    _name = name;  }  public String getURL()  {    return _driverList.get(0).getURL();  }  /**   * Returns the driver config.   */  public DriverConfig createDriver()  {    DriverConfig driver = new DriverConfig(this);    _driverList.add(driver);    return driver;  }  /**   * Returns the driver config.   */  public DriverConfig createBackupDriver()  {    DriverConfig driver = new DriverConfig(this);    _backupDriverList.add(driver);    return driver;  }  /**   * Sets a driver parameter.   */  public void setInitParam(InitParam init)  {    DriverConfig driver = _driverList.get(0);    HashMap<String,String> params = init.getParameters();    Iterator<String> iter = params.keySet().iterator();    while (iter.hasNext()) {      String key = iter.next();      driver.setInitParam(key, params.get(key));    }  }  /**   * Sets the jdbc-driver config.   */  public void setJDBCDriver(Driver jdbcDriver)    throws SQLException  {    DriverConfig driver;    if (_driverList.size() > 0)      driver = _driverList.get(0);    else      driver = createDriver();    driver.setDriver(jdbcDriver);  }  /**   * Creates the connection config.   */  public ConnectionConfig createConnection()  {    return _connectionConfig;  }  /**   * Returns the connection config.   */  public ConnectionConfig getConnectionConfig()  {    return _connectionConfig;  }  /**   * Sets the jdbc-driver config.   */  public void setPoolDataSource(ConnectionPoolDataSource poolDataSource)    throws SQLException  {    DriverConfig driver;    if (_driverList.size() > 0)      driver = _driverList.get(0);    else      driver = createDriver();    driver.setPoolDataSource(poolDataSource);  }  /**   * Sets the jdbc-driver config.   */  public void setXADataSource(XADataSource xaDataSource)    throws SQLException  {    DriverConfig driver;    if (_driverList.size() > 0)      driver = _driverList.get(0);    else      driver = createDriver();    driver.setXADataSource(xaDataSource);  }  /**   * Sets the jdbc-driver config.   */  public void setURL(String url)    throws ConfigException  {    DriverConfig driver;    if (_driverList.size() > 0)      driver = _driverList.get(0);    else      throw new ConfigException(L.l("The driver must be assigned before the URL."));    driver.setURL(url);  }  /**   * Returns the connection's user.   */  public String getUser()  {    return _user;  }  /**   * Sets the connection's user.   */  public void setUser(String user)  {    _user = user;  }  /**   * Returns the connection's password   */  public String getPassword()  {    return _password;  }  /**   * Sets the connection's password   */  public void setPassword(String password)  {    _password = password;  }  /**   * Get the maximum number of pooled connections.   */  public int getMaxConnections()  {    return _maxConnections;  }  /**   * Sets the maximum number of pooled connections.   */  public void setMaxConnections(int maxConnections)  {    _maxConnections = maxConnections;  }  /**   * Get the total number of connections   */  public int getTotalConnections()  {    // return _connections.size();    return 0;  }  /**   * Sets the time to wait for a connection when all are used.   */  public void setConnectionWaitTime(Period waitTime)  {    long period = waitTime.getPeriod();    _connectionWaitTime = period;    if (period < 0)      _connectionWaitCount = 3600; // wait for an hour == infinity    else {      _connectionWaitCount = (int) ((period + 999) / 1000);      if (_connectionWaitCount <= 0)        _connectionWaitCount = 1;    }  }  /**   * Gets the time to wait for a connection when all are used.   */  public long getConnectionWaitTime()  {    return _connectionWaitTime;  }  /**   * The number of connections to overflow if the connection pool fills   * and there's a timeout.   */  public void setMaxOverflowConnections(int maxOverflowConnections)  {    _maxOverflowConnections = maxOverflowConnections;  }  /**   * The number of connections to overflow if the connection pool fills   * and there's a timeout.   */  public int getMaxOverflowConnections()  {    return _maxOverflowConnections;  }  /**   * Sets the transaction timeout.   */  public void setTransactionTimeout(Period period)  {    _transactionTimeout = period.getPeriod();  }  /**   * Gets the transaction timeout.   */  public long getTransactionTimeout()  {    return _transactionTimeout;  }  /**   * Sets the max statement.   */  public void setMaxCloseStatements(int max)  {    _maxCloseStatements = max;  }  /**   * Gets the max statement.   */  public int getMaxCloseStatements()  {    return _maxCloseStatements;  }  /**   * Sets true if statements should be wrapped.   */  public void setWrapStatements(boolean isWrap)  {    _isWrapStatements = isWrap;  }  /**   * Sets true if statements should be wrapped.   */  public boolean isWrapStatements()  {    return _isWrapStatements;  }  /**   * Returns the prepared statement cache size.   */  public int getPreparedStatementCacheSize()  {    return _preparedStatementCacheSize;  }  /**   * Sets the prepared statement cache size.   */  public void setPreparedStatementCacheSize(int size)  {    _preparedStatementCacheSize = size;  }  /**   * Get the time in milliseconds a connection will remain in the pool before   * being closed.   */  public long getMaxIdleTime()  {    if (_maxIdleTime > Long.MAX_VALUE / 2)      return -1;    else      return _maxIdleTime;  }  /**   * Set the time in milliseconds a connection will remain in the pool before   * being closed.   */  public void setMaxIdleTime(Period idleTime)  {    long period = idleTime.getPeriod();    if (period < 0)      _maxIdleTime = Long.MAX_VALUE / 2;    else if (period < 1000L)      _maxIdleTime = 1000L;    else      _maxIdleTime = period;  }  /**   * Get the time in milliseconds a connection will remain in the pool before   * being closed.   */  public long getMaxPoolTime()  {    if (_maxPoolTime > Long.MAX_VALUE / 2)

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?