/*
* 得到池空未连接数
* * */
public static int getNullPool(String name)
{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if (pool != null)
{
return pool.getNullPool();
}else{
return 0;
}
} /*
* 得到ORACLE 执行错误代码
*
* */
public static int getOracleErr(String name)
{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if (pool != null )
{
return pool.getOracleErr();
}else{
return 0;
}
} /*
* 释放指定连接
* * */
public void freeConnection(String name, Connection con)
{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if (pool != null)
{
pool.freeConnection(con);
}
} /**
* 获得一个可用的(空闲的)连接.如果没有可用连接
* 且已有连接数小于最大连接数
* 限制,则创建并返回新连接
*
* @param name 在属性文件中定义的连接池名字
* @return Connection 可用连接或null
*/
public Connection getConnection(String name)
{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
if(pool != null)
{
return pool.getConnection();
}
return null;
}
/*
* 关闭连接池, 撤销驱动
*
* */
public synchronized void release()
{
// 有大于一个连接池管理类的实例时, 返回
if ( --clients != 0)
{
return ;
}
else // 只有一个连接池管理类的实例
{
Enumeration allPools = pools.elements();
while (allPools.hasMoreElements())
{
DBConnectionPool pool = (DBConnectionPool)allPools.nextElement();
pool.release();
}
Enumeration allDrivers = drivers.elements();
while(allDrivers.hasMoreElements())
{
Driver driver = (Driver)allDrivers.nextElement();
try{
DriverManager.deregisterDriver(driver);
log("撤销JDBC驱动程序: " + driver.getClass().getName()+"的注册");
}catch(SQLException e){
log(e, "无法撤销下列JDBC驱动程序的注册 " + driver.getClass().getName());
}
}
}
}
/**
* 测试指定连接池的连接情况
*/
public static void test(String name)
{
DBConnectionPool pool = (DBConnectionPool)pools.get(name);
pool.test();
}/**
* 从空闲连接池获得一个可用连接.如没有空闲的连接且当前连接数小于最大连接
* 数限制,则创建新连接.如原来登记为可用的连接不再有效,则从向量删除之,
* 然后递归调用自己以尝试新的可用连接.
*/
/**
* 此内部类定义了一个连接池.它能够根据要求创建新连接,直到预定的最
* 大连接数为止.在返回连接给客户程序之前,它能够验证连接的有效性.
*/
class DBConnectionPool
{
private int sum;
private int checkedOut;
Vector freeConnections = new Vector();
private int maxConn; // 连接数限制
private int max; // 总连接数(空闲+非空闲)
private String name;
private String password;
private String URL;
private String user;
// 使用getConnection没有得到连接, 返回null 的个数
public DBConnectionPool(String name ,
String URL , String user, String password, int maxConn)
{
this.name = name; // 连接池名称
this.URL = URL; // 数据库连接URL
this.user = user; // 数据库用户
this.password = password; // 数据库密码
this.maxConn = maxConn; // 最大连接数
}
* 将不再使用的连接返回给连接池
*
* @param con 客户程序释放的连接
*/
public synchronized void freeConnection(Connection con)
{
/**-----------**/
// 测试连接的有效性, 可以去掉
testConn(con);
/**-----------**/
if(con!=null)
{
/***----***/
// 将指定连接加入到向量末尾
freeConnections.addElement(con);
/***----***/
// 减少正在使用的连接数量
checkedOut--;
}
/**-----------**/
notifyAll();
}
public synchronized Connection getConnection()
{
Connection con = null;
if(freeConnections.size() > 0)
{
// 获取向量中第一个可用连接
con = (Connection)freeConnections.firstElement();
freeConnections.removeElementAt(0);
try{
if(con.isClosed())
{
log("从连接池" + name + "删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getConnection();
}
}catch(SQLException e) {
log("从连接池" + name + "删除一个无效连接");
// 递归调用自己,尝试再次获取可用连接
con = getConnection();
}
} else if(maxConn == 0 || checkedOut < maxConn){
con = newConnection();
} else { // 大于连接数限制
System.out.println(" 连接池取空,等待回收!");
isNullPool++ ;
}
if(con != null)
{
checkedOut++;
sum++;
}
testConn(con);
return con;
}
/**
* 从连接池获取可用连接.可以指定客户程序能够等待的最长时间
* 参见前一个getConnection()方法.
*
* @param timeout 以毫秒计的等待时间限制
*/
public synchronized Connection getConnection(long timeout)
{
long startTime = new Date().getTime();
Connection con;
while( (con = getConnection()) == null)
{
try
{
wait(timeout);
}
catch(InterruptedException e)
{}
if( (new Date().getTime() - startTime) >= timeout)
{
// wait()返回的原因是超时
return null;
}
}
return con;
}
/**
* 关闭所有连接
*/
public synchronized void release()
{
Enumeration allConnections = freeConnections.elements();
while(allConnections.hasMoreElements())
{
Connection con = (Connection)allConnections.nextElement();
try
{
con.close();
log("关闭连接池" + name + "中的一个连接");
}
catch(SQLException e)
{
log(e, "无法关闭连接池" + name + "中的连接");
}
}
freeConnections.removeAllElements();
}
/**
* 创建新的连接
*/
private Connection newConnection()
{
Connection con = null;
try
{
if(user == null)
{
con = DriverManager.getConnection(URL);
}
else
{
con = DriverManager.getConnection(URL, user, password);
}
/**-------------------------------------------------------------**/
// 每建一个连接此值都将增加
max++;
/**-------------------------------------------------------------**/
log("连接池" + name + "创建一个新的连接");
}
catch(SQLException e)
{
//以下注释实在数据库连接调试正常的情况下,因为以下的情况概率最大,所以没有提示连接地址错误
log(e, "Oracle来不及响应,无法创建下列URL的连接: " + URL);
//System.out.println(" Oracle来不及响应!");
isOracleErr ++ ;
return null;
}
return con;
}
/*
* 得到当前连接数非空闲
* */
public int getCurConns()
{
return checkedOut;
}
/*
* 得到程序调用连接的总次数
* 一个连接可能被调用多次
* **/
public int getSumConns()
{
return sum ;
}
/*
* 得到总的连接数(空闲+非空闲)
* ***/
public int getMaxConns()
{
return max;
}
public int getNullPool()
{
return isNullPool;
}
public int getOracleErr()
{
return isOracleErr ;
}
public void test()
{
System.out.println("\r\n\r\n--------------------vect.size="+freeConnections.size()+"\r\n\r\n");
for(int i=0;i<freeConnections.size();i++)
{
Connection conn = (Connection)freeConnections.get(i);
testConn(conn);
}
}
public void testConn(Connection conn)
{
try
{
if(conn.isClosed())
{
System.out.println("连接池错误:当前连接有问题:该连接破坏!");
}
Statement stm = conn.createStatement();
ResultSet rs = stm.executeQuery("select count(*) from sms");
rs.next();
rs.close();
stm.close();
//System.out.println(i+"="+rs.getInt(1));
}
catch(SQLException s){System.out.println("连接池错误:当前连接有问题:"+s);}
}
}
}