论坛首页 入门技术论坛

我的处女贴:连接池释放连接异常!

浏览 9957 次
该帖已经被评为新手帖
作者 正文
   发表时间:2006-11-18  
终于熬到注册第三天了,故迫不及待发表我的第一个帖子,因为最近已经被这东西折腾的不行了!这段时间做一网站,没有用到持久层,用Weblogic9.1做Web服务器(知道很浪费:))配了两个连接池,分别是局域网的另外两台机器上的,一个是SQLServer,一个是Oracle,这两个数据库的特点是SQLServer的访问量很大,因为很多别的系统在用,有时会报出“NetWork error IOException,The address already in use:connect” ,Oracle机烂---PIII900的机器,临时空间不够,连接数多了就会报出“ORA 04031 无法分配***字节的共享内存("large pool",.......)”,连接池的参数大概是设置5个初始连接,每次增长5个,最大值设的比较大-4000,整个系统大概有150人左右使用,但是SQLServer的连接池经常会到2000多个连接,甚至到3000多个,不知道是什么原因,另外我的代码部分是用一个单例类管理连接,一个多例类供外界调用,多例类中的代码格式是:
public List methodA(String sql){
    Connection conn=null;
    Statement stmt = null;
    ResultSet result=null;
    ....do something
    finally{
closeResult(result);
closeStatm(stmt);
closeConn(conn);
    }
}
   发表时间:2006-11-18  
而且之前不还试过Tomcat5.0+DBCP、Tomcat5.0+C3P0、Tomcat5.0+proxool、Weblogic+proxool,都有连接部不能正常释放的问题,我现在想用Tomcat5.5.2+proxool,不知道会不会好一些
0 请登录后投票
   发表时间:2006-11-18  
第一次发帖,不知道用上面的“Code”键,重新发一下代码:
/**
	     * 获取数据库连接
	     * @throws Exception
	     * @return boolean
	     */
	    public Connection connect() throws Exception{
	         Connection conn = null;
	         if(connType!=0&&connType!=1&&connType!=2)
	        	 throw new Exception("您输入的数据库连接类型"+connType+"不存在");
	         try{
        		 Db_sql cm=Db_sql.getInstance();
                 conn = cm.getConnection(dbname,connType);
	         }catch(Exception e){
	            logger.info("取得数据连接失败:");
	            e.printStackTrace();
	            throw e;
	         }
	         return conn;
	     }
	    

	    /**
	   * @function close
	   * @throws Exception
	   */
	  private void closeConn(Connection conn){
		  try{
			  Db_sql.getInstance().disConnect(conn);
		  }
		  catch(Exception e){
			  e.printStackTrace();
		  }
	  }
	  
	  private void closeStatm(Statement statm){
		  try{
			  if(statm!=null){
				  statm.close();
			  }
		  }
		  catch(Exception e){
			  e.printStackTrace();
		  }
	  }
	  
	  private void closeResult(ResultSet rs){
		  try{
			  if(rs!=null){
				  rs.close();
			  }
		  }
		  catch(Exception e){
			  e.printStackTrace();
		  }
	  }
public List executeQuery(String sql) throws Exception{
	    	Connection conn=null;
	        Statement stmt = null;
	        ResultSet result=null;
	        List list = new ArrayList();
	        //logger.info("sql:"+sql);
	        try{
	        	conn=this.connect();
	        	stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
	    		if(result != null){
	    			result.close();
	    			result = null;
	    		}
	    		if(stmt==null) System.err.println("statement is null");
	    		result = stmt.executeQuery(sql);
	          ResultSetMetaData rsmd = result.getMetaData();
	          while ( result.next() ){
	            Map map = new HashMap();
	            for ( int i = 1; i <= rsmd.getColumnCount(); i++ ){
	              map.put(rsmd.getColumnName(i), result.getObject(i));
	              //System.out.println("name----"+rsmd.getColumnName(i));
	            }
	            list.add(map);
	          }
	        }
	        catch ( Exception e ){
	     	 logger.info("sql:"+sql);
	          e.printStackTrace();
	        }
	        finally{
	            closeResult(result);
	            closeStatm(stmt);
	            closeConn(conn);
	        }
	        return list;
	     }
0 请登录后投票
   发表时间:2006-11-18  
public class ConnManager {

	  /***
	   *通过一个对象锁来控制数据库连接的同步
	   */
	 public static Object lock=new Object();
	 /**
	  *
	  */
	 public static ConnManager connManager=null;
	 /**   * 这个数据库连接成员只有在与数据库直接建立连接的情况下是有效的   */

	  private Connection conn = null;

	 /**   * 当这个参数有效时,表明程序是从连接池里取得连接。   */
	 private String datasource;
	 private ConnManager(){
	 }
	 /**
	  *
	  * @return single instance
	  */
	 public static ConnManager getInstance(){
	   if(connManager==null){
	     synchronized (lock) {
	        if(connManager==null){
	        	connManager=new ConnManager();
	        }
	     }
	   }
	   return connManager;
	 }

	 /*连接池类型 type:0--DBCP、C3P0等;1--proxool;2--Weblogic*/
	 public Connection getConnection(String datasource,int type) throws Exception {
		 DataSource ds = getDataSource(datasource,type);
		 try {
			 if(type!=1)
				 conn=ds.getConnection(); //每调用一次都返回一个连接池中的数据库连接
			 else{
				 Class.forName("org.logicalcobwebs.proxool.ProxoolDriver");
                 conn=DriverManager.getConnection("proxool."+datasource);
			 }
		 }catch(Exception dsex){
			 dsex.printStackTrace();
			 throw dsex;
		 }
		 return conn;
	 }
	 
	 private DataSource getDataSource(String datasource,int type)throws Exception{
		 DataSource ds =null;
		 if(type!=0&&type!=1&&type!=2){
			 throw new Exception("输入的连接池类型不存在:"+type);
		 }
		 else if(type==0){
			Context initCtx = new InitialContext();
            Context envCtx = (Context) initCtx.lookup("java:comp/env");
            ds = (DataSource) envCtx.lookup(datasource);
		 }
		 else if(type==2){
			Properties properties =  new Properties();
            properties.put(Context.INITIAL_CONTEXT_FACTORY,
                           "weblogic.jndi.WLInitialContextFactory");
            //properties.put(Context.PROVIDER_URL, "t3://127.0.0.1:7001");
        	Context ctx = new InitialContext(properties);
        	ds = (javax.sql.DataSource) ctx.lookup (datasource);
		 }
		 return ds;
	 }
	 
	  /**   * 释放连接,从连接池中取得的连接那么释放传来的连接   * @param conn
	   */
	  public void disConnect(Connection connection) throws Exception {
	      try {
	        if (connection != null) {
	           connection.close();
	        }
	      }catch (Exception ex) {
	        throw ex;
	      }
	  }

}
0 请登录后投票
   发表时间:2006-11-19  
帖出来已经1天了,只有人浏览,没有人回复,不知道是大家都不知道怎么解决,还是觉得问题太简单不屑于回答,又或是不原意帮助一个论坛的新人,反正比起刚开始发现这论坛时候的兴奋,现在已经是心灰意冷了!
0 请登录后投票
   发表时间:2006-11-19  
别怪别人不帮你,这Db_sql和ConnManager应该是一个类吧?

初步判断,DataSource重复创建,占用了大量连接,并且失去了DS的意义
0 请登录后投票
   发表时间:2006-11-19  
deafwolf 写道
别怪别人不帮你,这Db_sql和ConnManager应该是一个类吧?

初步判断,DataSource重复创建,占用了大量连接,并且失去了DS的意义
非常感谢deafwolf的回复,呵呵,我是有些心急了,因为这是一个已经上线了的项目,每次出问题后果都很严重,望见谅。Db_sql和ConnManager的确是同一个类,但是这个类我使用了单例模式,应该不会重复创建DataSource吧。
0 请登录后投票
   发表时间:2006-11-19  
抱歉,我没从你的代码中看出单态的所在
对于公用的连接类,单态的应该是类里的DS,而不是对这个类加锁

public class ConnManager{
  private static DataSource dataSource=null;
  private ConnManager(){};
  private static Connection getConnection(){
    if(dataSource==null){
      dataSource=...;
    }
    return dataSource.getConnection();
  }
}

0 请登录后投票
   发表时间:2006-11-19  
那为什么多个DataSource会造成占用大量连接呢,每个创建的连接不是都在方法结束的时候关闭连接了吗?而且deafwolf提到这样会失去DS的意义,又是什么原因呢,难道说DataSource的存在就一定应该是单态的吗?
0 请登录后投票
   发表时间:2006-11-20  
请楼主自己google一下连接池吧
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics