首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > Java Web开发 >

连接池占用资源有关问题

2011-12-05 
连接池占用资源问题本人第一次采用链接池链接数据库,可发现占用内存相当大。为什么会这样呢?我的链接池代码

连接池占用资源问题
本人第一次采用链接池链接数据库,可发现占用内存相当大。为什么会这样呢?
我的链接池代码如下:望各位高手指点一二!
package   com.nc138.util;

import   java.io.*;
import   java.sql.*;
import   java.util.*;
import   java.util.Date;

public   class   DBConnectionManager   {
static   private   DBConnectionManager   instance;   //   唯一实例

static   private   int   clients;

private   Vector   drivers   =   new   Vector();

private   PrintWriter   log;

private   Hashtable   pools   =   new   Hashtable();

Statement   stmt   =   null;

ResultSet   rs   =   null;

/**
  *   返回唯一实例.如果是第一次调用此方法,则创建实例
  *
  *   @return   DBConnectionManager   唯一实例
  **/
static   synchronized   public   DBConnectionManager   getInstance()   {
if   (instance   ==   null)   {
instance   =   new   DBConnectionManager();
}
clients++;
return   instance;
}

/**
  *   建构函数私有以防止其它对象创建本类实例
  */
private   DBConnectionManager()   {
init();
}

/**
  *   将连接对象返回给由名字指定的连接池
  *
  *   @param   name   在属性文件中定义的连接池名字
  *   @param   con   连接对象
  **/
public   void   freeConnection(String   name,   Connection   con)   {
DBConnectionPool   pool   =   (DBConnectionPool)   pools.get(name);
if   (pool   !=   null)   {
pool.freeConnection(con);
}
}

public   Connection   getConnection(String   name)   {
DBConnectionPool   pool   =   (DBConnectionPool)   pools.get(name);
if   (pool   !=   null)   {
return   pool.getConnection();
}
return   null;
}


public   Connection   getConnection(String   name,   long   time)   {
DBConnectionPool   pool   =   (DBConnectionPool)   pools.get(name);
if   (pool   !=   null)   {
return   pool.getConnection(time);
}
return   null;
}

public   synchronized   void   release()   {
//   等待直到最后一个客户程序调用
if   (--clients   !=   0)   {
return;
}

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());
}
}
}

private   void   createPools(Properties   props)   {
Enumeration   propNames   =   props.propertyNames();
while   (propNames.hasMoreElements())   {


String   name   =   (String)   propNames.nextElement();
if   (name.endsWith( ".url "))   {
String   poolName   =   name.substring(0,   name.lastIndexOf( ". "));
String   url   =   props.getProperty(poolName   +   ".url ");
if   (url   ==   null)   {
log( "没有为连接池 "   +   poolName   +   "指定URL ");
continue;
}
String   user   =   props.getProperty(poolName   +   ".user ");
String   password   =   props.getProperty(poolName   +   ".password ");
String   maxconn   =   props.getProperty(poolName   +   ".maxconn ",   "0 ");
int   max;
try   {
max   =   Integer.valueOf(maxconn).intValue();
}   catch   (NumberFormatException   e)   {
log( "错误的最大连接数限制:   "   +   maxconn   +   "   .连接池:   "   +   poolName);
max   =   0;
}
DBConnectionPool   pool   =   new   DBConnectionPool(poolName,   url,
user,   password,   max);
pools.put(poolName,   pool);
log( "成功创建连接池 "   +   poolName);
}
}
}

/**
  *   读取属性完成初始化
  */


[解决办法]
感觉这样做连接池好复杂啊

我的理解是配置数据源时就可以配置数据池,
在servlet.xml里配置Resource.如以下代码:

<ResourceParams name= "jdbc/BookDB ">
<parameter>
<name> factory> </name>
<value> org.apache.commons.dbcp.BasicDataSourceFactory </value>
</parameter>
<parameter>
<name> maxActive </name>
<value> 100 </value>
</parameter>
<parameter>
<name> maxIdle </name>
<value> 30 </value>
</parameter>
<parameter>
<name> maxWait </name>
<value> 10000 </value>
</parameter>
<parameter>
<name> username </name>
<value> dbuser </value>
</parameter>
<parameter>
<name> password </name>
<value> 1234 </value>
</parameter>

<parameter>
<name> driverClassName </name>
<value> com.mysql.jdbc.Driver </value>
</parameter>
<parameter>
<name> url </name>
<value> jdbc:mysql://localhost:3306/BookDB?autoReconnect=true </value>
</parameter>
</ResourceParams>

再在web.xml里引用数据源,如以下代码:
<resource-ref>
<description> DB Connection </description>
<res-ref-name> jdbc/BookDB </res-ref-name>
<res-type> javax.sql.DataSource </res-type>
<res-auth> Container </res-auth>
</resource-ref>

最后在代码中通过JNDI取得连接,如以下代码:
public class BookDB {
private ArrayList books;


private DataSource ds=null;

public BookDB() throws Exception{
Context ctx=new InitialContext();
if(ctx==null)
throw new Exception( "No Context ");
ds=(DataSource)ctx.lookup( "java:com/env/jdbc/BookDB ");
}

public Connection getConnection() throws Exception {
return ds.getConnection();
}

public void closeConnection(Connection con){
try{
if(con!=null) con.close();
}catch(Exception e){
e.printStackTrace();
}
}
......

}

不知这样行不行,仅供参考。
[解决办法]
学习

热点排行