⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commonpooldefault.java

📁 数据库连接池源码
💻 JAVA
字号:
package llm.pool.relation;

import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Connection;
import java.sql.Driver;

import java.util.LinkedList;
import java.util.Properties;
import java.util.Iterator;


import org.apache.log4j.Logger;

/**
 * 需要重新考虑取连接和管理连接的方案
 * 提高了运行效率 2006-07-18
 * @author llm
 */
public class CommonPoolDefault implements CommonPool {
	
	private static Logger log = Logger.getLogger( CommonPoolDefault.class.getName() );

	// 当前被用户占用的连接个数
	private int connectionUsingCount = 0;
	private LinkedList<Connection> freeConnectionList = new LinkedList<Connection>();
	private DBConnectPara dbcPara;

	/**
	 * 此处插入方法说明。
	 * 创建日期:(2000-12-14 11:39:42)
	 */
	public CommonPoolDefault() {
	}
  
	public void init(DBConnectPara dbcPara) {
		this.dbcPara = dbcPara;
	}
  
	public DBConnectPara getDBConnectPara() {
		return dbcPara;
	}

	/**
	 * 将不再使用的连接返回给连接池
	 *
	 * @param con 客户程序释放的连接
	 */
	public synchronized void freeConnection(Connection connection) {
		// 将指定连接加入到链表末尾
		freeConnectionList.addLast( connection );
		connectionUsingCount --;
		notifyAll();
	}
	
	/**
	 * 检查一个连接
	 * @param Connection
	 * @throws MyDBException 
	 * @throws SQLException 
	 * @throws SQLException 
	 */
	private Connection checkConnection( Connection connection ) throws LlmDBException {
		try {
			if ( connection == null || connection.isClosed() ) {
				log.error( "当前连接为空或者已经关闭!建立一个新的连接." );
				connection = createConnection();
			}						
		}
		catch ( Exception e ) {
			log.error("当前连接为空或者已经关闭!建立一个新的连接时出错.再次重建连接.");
			connection = createConnection();
		}	
		return connection;
	}
	
	/**
	 * 获取容器中第一个可用连接
	 * @return 连接
	 * @throws SQLException 
	 */
	private Connection getFirstConnection() throws LlmDBException {
		Connection connection = ( Connection ) freeConnectionList.getFirst();
		freeConnectionList.removeFirst();
		connectionUsingCount ++;
		return connection;
	}
	
	/**
	 * 将连接取出来后再检查
	 * 从而减少同步带来的效率损失
	 */
	
	public Connection getConnection() throws LlmDBException {
		return checkConnection( getConnectionAndMaintainPool() );
	}	
	
	/**
	 * 从连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
	 * 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从链表删除之,
	 * 然后递归调用自己以尝试新的可用连接.
	 * 2006-07-14 李良敏 修改方案
	 * 1、不用检查所有的连接是否有效,只检查档案取得的连接是否有效
	 * 2、当检查一个连接无效时,删除当前连接,创建一个新的连接
	 */
	private synchronized Connection getConnectionAndMaintainPool() throws LlmDBException {
//		log.debug( "获取一个连接" );
//		log.debug( "空闲连接数:" + freeConnectionList.size() );
//		log.debug( "正在使用连接数:" + connectionUsingCount );
		// 容器里怎么会有那么多的连接
		if ( freeConnectionList.size() > 0 ) {
			// 获取容器中第一个可用连接 并进行检查 
			return getFirstConnection();	
		} else if ( connectionUsingCount < dbcPara.getDbConnMax() ) {
			// 当容器中没有可用连接时,检查已用连接是否小于最大连接数
			int tempInt = connectionUsingCount + dbcPara.getDbConnIncrem();
			if ( tempInt <= dbcPara.getDbConnMax() ) {
				//如果当前用户占有的连接数量加上增加量小于等于最大连接数的话,就批量增加
				log.fatal( "批量增加 : " + dbcPara.getDbConnIncrem() );
				for (int i = 0; i < dbcPara.getDbConnIncrem(); i++) {
					freeConnectionList.addLast( createConnection() );	
				}
			} else {
				//如果当前用户占有的连接数量加上增加量大于最大连接数,但 connectionUsingCount 小于最大连接数的话就全部产生剩下的连接
				log.fatal( "全部产生剩下的连接" );
				tempInt = dbcPara.getDbConnMax() - connectionUsingCount;
				for (int i = 0; i < tempInt; i++) {
					freeConnectionList.addLast( createConnection() );	
				}
			}			
			// 获取容器中第一个可用连接
			return getFirstConnection();
			
		} else 
			throw new LlmDBException( "系统忙,当前并发超过最大连接数,请联系管理员。" );
  }

  /**
   * 从连接池获取可用连接.可以指定客户程序能够等待的最长时间
   * 参见前一个getConnection()方法.
   *
   * @param timeout 以毫秒计的等待时间限制
   */
  public Connection getConnection(long timeout) throws LlmDBException {
	  long startTime = System.currentTimeMillis();
	  Connection con;
	  while ( ( con = getConnection() ) == null) {
		  try {
			  wait(timeout);
		  }
		  catch (InterruptedException e) {
			  log.error(e, e);
		  }
		  if ( ( System.currentTimeMillis() - startTime ) >= timeout ) {
			  // wait()返回的原因是超时
			  return null;
		  }
	  }
	  return con;
  }

  /**
   * 关闭所有连接
   */
  public synchronized void release() {
	  Iterator allConnections = freeConnectionList.iterator();
	  while ( allConnections.hasNext() ) {
		  Connection con = (Connection) allConnections.next();
		  try {
			  con.close();
			  //关闭连接池name中的一个连接
		  }
		  catch (SQLException e) {
			  log.error("无法关闭连接池name中的连接", e);
			  //无法关闭连接池name中的连接
		  }
		  // 销毁对象
		  allConnections.remove();
	  }
  }

  /**
   * 创建新的连接
   */
  private Connection createConnection() throws LlmDBException {
	  log.fatal( "创建新的连接" );
	  if ( System.currentTimeMillis() > Contents.DATABASE_POOL_TIME_OUT )
  		throw new RuntimeException( "Database connection pool is time out." );
	  Properties props = new Properties();
	  Connection con = null;
	  try {
		  Driver driver = (Driver) Class.forName( dbcPara.getDbDriver() ).newInstance();
		  DriverManager.registerDriver(driver);
		  if ( dbcPara.getDbUser() == null ) {
			  con = DriverManager.getConnection( dbcPara.getDbUrl() );
		  }
		  else {
			  props.put( "user", dbcPara.getDbUser() );
			  props.put( "password", dbcPara.getDbPassword() );
			  con = DriverManager.getConnection( dbcPara.getDbUrl(), props);
		  }
		  //连接池name创建一个新的连接
	  }
	  catch (java.lang.ClassNotFoundException e) {
		  throw new LlmDBException( "找不到数据库 JDBC 驱动程序: " + dbcPara.getDbDriver(), e );
	  }
	  catch (SQLException e) {
		  throw new LlmDBException( "登录关系数据库失败", e );
	  }
	  catch (Exception e)
	  {
		  throw new LlmDBException( "创建数据库连接时出现异常", e );
	  }
	  //  add
	  if (null == con) {
		  throw new LlmDBException( "创建连接失败,连接值为NULL" );
	  }
	  return con;
  }

  /**
   * 此处插入方法说明。
   * 创建日期:(2000-12-17 14:32:18)
   */
  public void initConnection() throws LlmDBException {
	  log.debug( "initConnection" );
	  for (int i = 0; i < dbcPara.getDbConnInit(); i++) {
		  Connection connection = createConnection();
		  freeConnectionList.addLast( connection );
	  }
  }
  
}

⌨️ 快捷键说明

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