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> * <database name='jdbc/test'> * <init> * <driver>postgresql.Driver</driver> * <url>jdbc:postgresql://localhost/test</url> * <user>ferg</user> * <password>foobar</password> * </init> * </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 + -
显示快捷键?