看了以前同事写的一个数据库连接池的实现,他继承了thread类,并且定时执行refresh()方法,
我的疑问是这个方法有必要吗?在从连接池取连接的时候做一些操作如
1.有可用的连接,从连接池中得到一个可用连接并返回
2.没有可用连接,但是连接池还没有达到最大,新建一个
3.重复以上直到超时给出提示。
我想有以上这个也就差不多了,这个refresh方法有点多余吧?我网上也搜了一些代码好像都没有这个操作。
不知道各位大哥在实际项目中是怎么实现的?另外如果用DBCP的话,哪些操作已经被它封装了?我只要实现哪些就可以了?
 /**
   * refresh the connection pool
   * if some connection is not used, than remove it
   * than get a new one
   */
  private synchronized void refresh(){
    log("refresh:time is going!" + "  counter=" + counter);
    counter++;    // 复制一个原来的连接池,然后对原来的池进行更新
    Vector tempPool =(Vector)pool.clone();
    pool = new Vector();
    log("refresh:begin pool size=" + tempPool.size());
    long now = System.currentTimeMillis();  // get now time    /*
     * 循环逐一查看原来的池中的数据库连接
     * 如果连接空闲过久或被使用过多,则要关闭该连接,
     * 然后从重新建立一个新的连接
     * 如果连接被连接过久,则认为是用户忘掉释放连接
     * 程序要强制释放该连接
     */
    Enumeration epool = tempPool.elements();
    while(epool.hasMoreElements()){
      PoolEntry entry =(PoolEntry)epool.nextElement();
      // 确保连接入口不为空
      if(entry != null){
        // 数据库连接已经创建的时间
        long creationAge = now - entry.getCreationTime();
        // 数据库连接空闲了的时间
        long freeAge = now - entry.getLastUsedTime();
        // 根据连接的状态不同而进行不同的处理
        switch(entry.getState()){
          case PoolEntry.AVAILABLE:   // 可用
            if(!entry.isValid()){
            //  log("connection was close by some unknown problem!");
            //  log(entry.toString());
              break;    // 跳过
            }
            // 判断是否被使用次数过多
            if(entry.getTimesUsed() > maxTimesUsed){
//              log("refresh: used too many times,Connection:" + entry.getHandle());
//              log(entry.toString());
              entry.close();
            // 判断是否创建的时间过久
            }else if(creationAge > maxCreationAge){
              // large than maxCreationAge, close the connection
//              log("refresh: created too old!Connection:" + entry.getHandle());
//              log(entry.toString());
              entry.close();
            // 判断是否空闲过久
            }else if(freeAge > maxFreeAge){
//              log("refresh: free too long!Connection:" + entry.getHandle());
//              log(entry.toString());
              entry.close();
            }else{
            //  log("add used entry");
            //  log(entry.toString());
              // 让连接回到池中重用
              pool.addElement(entry);
            }
            break;
          case PoolEntry.IN_USE:
            // now conn in use, so put it to the new pool
            long usedAge = System.currentTimeMillis() - entry.getUsedTime();
            // 如果同一个连接被同一个用户连接过久
            // 则认为是用户忘掉释放或程序出错一起未释放
            // 要程序强制将其释放并判定是否可以重用
            if(usedAge > maxUsedAge){
//              log("refresh: used too long,Connection:" + entry.getHandle());
              //log(entry.toString());
              // 再判断连接是否创建过久,如果是就关闭该连接,
              // 否则释放该连接并让其回到连接池中
              if(creationAge > maxCreationAge)
                  entry.close();
              else{
                entry.release();
                pool.addElement(entry);
//                log("one connection was connected to long, now reuse it!....");
//                log(entry.toString());
              }
            }else{
              pool.addElement(entry);
            }
            break;
        }
      }
    }      // check the pool size,whether the size less than the minSize
      //log("pool size = " + pool.size());
      // 如果连接数量少于最小数量
      // 添加一些新连接补充连接池
      int deficit = minSize - pool.size();
      // 少于最小连接数
      if(deficit > 0){
//        log("refresh:the pool size is less than minSize.");
//        log("refresh:new pool size=" + pool.size());
        // 差多少补多少
        for(int i = 0; i < deficit; i++){
          try{
            //********************************************
            // 这里如果建立连接失败,应该有几次重试才对
            //*************************************************
            Connection conn = createNewConnection();
            if(DB.checkConnection(conn)){
              PoolEntry tempBean = new PoolEntry(conn);
              tempBean.release();
              pool.addElement(tempBean);
//              log("refresh:add a bean to the pool");
//              log(entry.toString());
            }
          }catch(Exception e){
            log(e,e.getMessage());
          }
        }
      }
      // notify there may be free connction
      this.notify();
//    log("refresh:end");
  }  public void run(){
    while(true){
      try{
        // 等待下一次刷新
        this.sleep(refreshFrequency);
        // 刷新连接池
        this.refresh();
      }catch(InterruptedException itEx){
        log("System interrupte:" + itEx.getMessage());
      }
    }
  }

解决方案 »

  1.   

    DBCP提供了连接池,你只需要配置就行了
      

  2.   

    我用过StandardXAPoolDataSource数据源,没看过源码,不过感觉应该封装了refresh方法。
    无缘无故总给我打LOG出来告诉我连接的情况,愁死我了。
      

  3.   


    我说的不是WEB程序,是应用程序,这个要自己写吧
      

  4.   


    不需要!Java 开源的连接池可以用于任何 Java 应用程序! 
      

  5.   

    不要试图去写个什么连接池。实现一个可靠的连接池是极其复杂的,难度非常之高。常用开源的连接池有 c3p0, dbcp, proxool拿 C3P0 来说,共有 33 个可以自行配置的参数。DBCP 是 Apache 的产品,应该属于“名牌”了吧,结果呢?DBCP 的使用已经减少,且 Hibernate 已经放弃了对 DBCP 的支持。
      

  6.   

    这位大哥哪有C3P0的小程序例子啊,网上都是基于WEB的