当前位置:  技术问答>java相关

讨论下数据库连接池的东东如何?(JSP+JavaBean+Oracle)有赏!

    来源: 互联网  发布时间:2015-10-15

    本文导语:  高分请教下各位高手. 现在正做着一个WEB的应用程序,JSP+JavaBean+Oracle,连接DB及逻辑处理均在BEAN的部分处理.因为访问量比较大,设想同时在线用户达到1000以上,DB的数据量达50万以上,如何用池化的连接进行性能的提高?各位...

高分请教下各位高手.
现在正做着一个WEB的应用程序,JSP+JavaBean+Oracle,连接DB及逻辑处理均在BEAN的部分处理.因为访问量比较大,设想同时在线用户达到1000以上,DB的数据量达50万以上,如何用池化的连接进行性能的提高?各位分享下这方面的经验如何?
    我试过使用一个网上找到的连接池的管理的东东,但那是在Servlet上用,我把她稍修改使用在JSP+BEAN上好似没有达到预期的效果.诚心请教各位.sourcecode better.

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

/**
* 管理类DBConnectionManager支持对一个或多个由属性文件定义的数据库连接
* 池的访问.客户程序可以调用getInstance()方法访问本类的唯一实例.
*/
public class DBConnectionManager {
  static private DBConnectionManager instance; // 唯一实例
  static private int clients;

  private Vector drivers = new Vector();
  private PrintWriter log;
  private Hashtable pools = new Hashtable();

  /**
  * 返回唯一实例.如果是第一次调用此方法,则创建实例
  *
  * @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);
    }
  }

  /**
  * 获得一个可用的(空闲的)连接.如果没有可用连接,且已有连接数小于最大连接数
  * 限制,则创建并返回新连接
  *
  * @param name 在属性文件中定义的连接池名字
  * @return Connection 可用连接或null
  */
  public Connection getConnection(String name) {
    DBConnectionPool pool = (DBConnectionPool) pools.get(name);
    if (pool != null) {
      return pool.getConnection();
    }
    return null;
  }

  /**
  * 获得一个可用连接.若没有可用连接,且已有连接数小于最大连接数限制,
  * 则创建并返回新连接.否则,在指定的时间内等待其它线程释放连接.
  *
  * @param name 连接池名字
  * @param time 以毫秒计的等待时间
  * @return Connection 可用连接或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());
      }
    }
  }

  /**
  * 根据指定属性创建连接池实例.
  *
  * @param props 连接池属性
  */
  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);
      }
    }
  }

  /**
  * 读取属性完成初始化
  */
  private void init() {
    InputStream is = getClass().getResourceAsStream("/db.properties");
    Properties dbProps = new Properties();
    try {
      dbProps.load(is);
    }
    catch (Exception e) {
      System.err.println("不能读取属性文件. " +
      "请确保db.properties在CLASSPATH指定的路径中");
      return;
    }
    String logFile = dbProps.getProperty("logfile", "DBConnectionManager.log");
    try {
      log = new PrintWriter(new FileWriter(logFile, true), true);
    }
    catch (IOException e) {
      System.err.println("无法打开日志文件: " + logFile);
      log = new PrintWriter(System.err);
    }
    loadDrivers(dbProps);
    createPools(dbProps);
  }

  /**
  * 装载和注册所有JDBC驱动程序
  *
  * @param props 属性
  */
  private void loadDrivers(Properties props) {
    String driverClasses = props.getProperty("drivers");
    StringTokenizer st = new StringTokenizer(driverClasses);
    while (st.hasMoreElements()) {
      String driverClassName = st.nextToken().trim();
      try {
        Driver driver = (Driver)Class.forName(driverClassName).newInstance();
        DriverManager.registerDriver(driver);
        drivers.addElement(driver);
        log("成功注册JDBC驱动程序" + driverClassName);
      }
      catch (Exception e) {
        log("无法注册JDBC驱动程序: " +
        driverClassName + ", 错误: " + e);
      }
    }
  }

  /**
  * 将文本信息写入日志文件
  */
  private void log(String msg) {
    log.println(new Date() + ": " + msg);
  }

  /**
  * 将文本信息与异常写入日志文件
  */
  private void log(Throwable e, String msg) {
    log.println(new Date() + ": " + msg);
    e.printStackTrace(log);
  }

|
你应该在第一次使用的时候就建立这个连接池,以后只从里面取一个连接就可以了,退出的时候关闭这个连接池(根据static private int clients这个来判断是否为最后一个客户程序调用,如果是就关闭)。
我在用DBConnectionManager时加了下面一个方法,作用是得到这个连接池,但并不为这个连接池的客户数加一,这样总是保持同一时间只会建立一次连接池。在用户退出时才关闭连接池。
static synchronized public DBConnectionManager getConnectionPool()
{
if(instance == null)
{
instance = getInstance();
}
return instance;
}

|
告诉我你的邮箱,我给你发一份程序
它是用xml来做配置文件的
已经在一个网站项目中用过了,非常好用

|
用tomcat可以配置连接池,在server.xml中有例子:
如:
  
        
         
            usermyuser
passwordmypasswd
            driverClassName
       oracle.jdbc.driver.OracleDriver
            driverName
jdbc:oracle:thin:@mydbserver:1521:mydbsid

我在用jdbc-odbc桥方式时也出数据库错误,用了一段时间就报连接错误;
用thin方式后没出过该毛病,
tomcat版本4.0.1

|
poolman不仅可以是数据库连接池,也可以做其他资源的缓冲池。
多看看它的文档,会对数据库连接池有跟进一步的了解。

对于大数据量测试,连接池就死掉,应该使用orion做服务器,监控数据连接释放情况。等真正体会了连接的创建和释放后再转为tomcat或其他。

tomcat4里面多了tyrex-0.9.7.0.jar,如果看看官方文档,就会发现在tomcat3.X时,这是个第三方的数据库连接池包。所以,建议使用现有的比较成熟的数据库连接池产品。不反对好学者自己研究研究。

|
http://jakarta.apache.org/tomcat/tomcat-4.0-doc/jndi-resources-howto.html

|
直接用J2EE ApplicationServer上的DataSource不就完了吗,要省钱那就用JDBC2.0可选包里的DataSource,下载数据库驱动,比如Oracle的JDBC驱动就有DataSource和连接池。

|
对了,我用Tomcat4.03的JNDI连接池的时候,一般访问不会出现错误。但我作
告负载的压力测试的时候,就会出现不知为什么,程序中的con.close()应该是将当前连接归还到连接池呀,不可能手工关闭物理连接的。

|
上述方法,已经不合适了,

应该采用jsp/servlet + ejb + dao + Oracle,来设计。

|
core servlet and JSP这本书里有一个连接池的例子,也许可以参考一下:

http://archive.coreservlets.com/Chapter18.html

|
to:lbluekey(蓝鸟) 
对这个东西con.close()我也有疑问,这样好象是关闭了实际连接,要用类似如datasource.close(con)方式关闭可能才用到连接池。

哪位已经知道的或者有时间的摸索一把给个解释吧

|
我是在servlet里直接import connect.*
代码基本与你写的一致,服务器为apache
数据库也是与webserver分离的,我刚才试着拔掉网线。还好啊。。


|
怎么不用poolman呢??
我觉得是一个不错的连接池

|
使用Oracle 的 JDBC 其中有对连接池的支持类!

|
我也是用上面的连接方式,WebServer用的是tomcat3.3.1,但我发现一个问题。就是当我进行多次不停的连接时,连接会出错,然后就再也连接不上了,当重起tomcat之后,又回复了正常。哪位大虾若是知道,请不吝赐教,谢了!

|
con.close()本来就是关闭实际的连接

|
aq.executeQuery: ORA-00020: maximum number of processes (59) exceeded
不看你的代码,就看看你的这个错误信息就很明显——资源、资源,没有释放!
上面是不是ASP或其他语言的写法,不要紧慢慢来,多看书,看好书~!

    
 
 
 
本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • http://www.itpub.net 论坛更换数据库,速度更快,欢迎大家前去讨论!
  • http://www.itpub.net 论坛更新数据库,速度更快,欢迎大家前去讨论unix&linux知识!
  • 讨论ejb中数据库操作问题
  • 和大家讨论一下,搞开发的人,数据库应该掌握到什么程度?
  • 讨论一个小问题(关于数据库查询结果)
  • 讨论:数据库操作的设计模式
  • Java数据库编程的问题,欢迎大家讨论。
  • 大家讨论一下用java访问数据库的效率。
  • 在一个比较大OA系统数据库设计时,有些表的主键设置成自增还是人工取最大值好呢,欢迎讨论
  • 讨论:J2EE数据库类的设计模式!
  • 公告:CSDN AIX论坛有奖话题讨论活动(八)——本期话题:除了数据库应用,还有哪些应用也可以运行于AIX系统之上?(和Linux系统相比较,性能更优)
  • 请高手讨论:关于数据库ResultSet 与 二维数组,进来有分
  • 谁能告诉我,做一个象网易那样的聊天室,用什么方法,不要告诉我是用数据库或读写文件,是不是用多线程,socket协议。来讨论者皆有分。
  • Java 可以做拨号程序吗?我只是和大家讨论讨论 不必太认真
  • 欢迎高手来讨论:关于文件格式的大讨论
  • 参数传递的问题!(大家讨论讨论)
  • 用java开发一个基于Proxy(代理)的网络计费系统。有兴趣的来讨论讨论
  • 哪位高手有兴趣跟我讨论讨论java中调用dll文件??小弟有些问题还是不很清楚??
  • 【讨论贴】gcc开发的时候有大家都有什么好的调试方法,来讨论下
  • 和Java版高手在线讨论代理服务器的问题,讨论者都有分。
  • 讨论讨论,当错误发生时,并用if语句测试出时,应该返回怎样的值
  • 一个面试,是“北京华胜六所”外包给风河(VxWorks)北京研发处,做linux内核开发,大家过来讨论讨论
  • 新建了个QQ群(软件与创业),希望有兴趣的朋友进来讨论讨论软件项目、产品、创业、管理、投资等(代码之外的)观点和想法
  • Java 访问控制的问题(public,private,protected,(default))!讨论讨论!
  • 用java做c/s结构可行吗???大家来讨论讨论,应该都会有收获。
  • 这两天本版人气不高,我来发个问题,有关互斥同步的。大家讨论讨论
  • 有没有人讨论value object模式
  • 讨论“内存泄漏”
  • 很专业的问题请教J2EE高手!这是一个讨论区,有请各位对J2EE感兴趣的朋友参加讨论!
  • 大家一起讨论讨论,suse和ubuntu的区别,顺便散散分
  • 对大家很有意义的一个问题,建议大虾、菜鸟们都来讨论讨论#¥#·#¥·#%#¥%#¥%


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3