📄 commonpooldefault.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 + -