CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
不看会后悔的Windows XP之经验谈 简单快捷DIY实用家庭影院
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  Java >  Web 开发

请教各位高手,数据库连接到底能有多大的资源消耗?

楼主princerock(princeVC)2003-02-04 16:08:01 在 Java / Web 开发 提问

1.如果我每次使用数据库都重新连接一次,会有什么后果(系统会因为重荷而崩溃吗)?  
   
  2.在连接数据库的各语句中,哪个消耗系统资源最严重?  
  Class.forName,  
  DriverManager.getConnection,  
  createStatement,  
  execute  
   
  3.我发现如果不及时断开数据库的连接,再次使用数据库就有可能出问题,而Java又没有C++的析构函数(finalize调用的太“不及时”了!),那么,应该如何设计与数据库部分的连接呢?每使用数据库就连接一次可行不可行呢,还有什么好办法解决这个问题? 问题点数:100、回复次数:4Top

1 楼dd777(grass)回复于 2003-02-04 17:06:37 得分 25

1.每次使用数据库都重新连接一次当然不好,如果拥护足够多,系统会死掉。  
      最好优化一下,不要太多的connection  
   
  2.这个我没经验,我想Class.forName,createStatement占用的少;getConnection,execute比较多吧。  
   
  3.   这确实是个问题,一般我不会直接在*.jsp中做sql、连接、关闭等操作,  
  做几个bean,把要作的动作都封起来,在   jsp中可以随时调用,效率会比较高;最好不要每使用数据库就连接一次,尽量优化吧,我尝试过。对于小用户量的系统,没什么区别。  
   
  祝好运!  
   
  Top

2 楼yysinger(singer)回复于 2003-02-04 17:48:07 得分 25

数据库的连接是占用的资源有两中资源,其一:数据库的连接数,其二:系统的内存资源,但是如果你所做的系统不是很大,访问量也不很大的情况下,不必考虑这个问题,每一次建立一个连接,之后关掉就可以了,因为使用使用数据库连接池还要考虑同步的问题,也是很复杂的Top

3 楼zhirenshao(我属老鼠)回复于 2003-02-04 19:17:42 得分 50

连接数据库是很费时间的一项工作,所以,如果你的每个JSP页面里都有DriverManager.getConnection()这句的话,那你的网站肯定要慢死了(除非你有超快的服务器)。  
   
  但是,如果你只建立一个连接,然后所有用户都使用这个连接,那肯定也慢死了,因为所有对数据库的查询和更新操作将一个一个地通过这个唯一的连接,发送到数据库。  
   
  比较好而且常用的解决办法有两个。第一个是使用连接池,任何对数据库的查询和存取并不是直接发往数据库,而是发到连接池,连接池可以管理这些对数据库的操作。它可以同时处理大量的对数据库的操作,而不是像只建立一个连接那样,一条一条处理。因为现在的数据库系统都是设计成多线程的,可以同时处理多个连接的。  
   
  下面重点来说说第二种方法,就是把数据库连接作为session的一部分。原理很简单。当有一个用户登陆你的网站时,为其新建一个数据库连接,例如  
  Connection   conn   =   DriverManager.getConnection("");  
   
  然后,把它放到session里面  
  session.setAttribute("servletapp.connection",conn);  
   
  于是conn这个对象就不会被销毁,因此此用户对数据库的连接就一直保留着,然后此用户若是在你网站上浏览论坛或者购物,一直都是用这个连接,而不用重新连接数据库,速度也就加快了。   直到他登出这个网站,或者session到期了,那么conn这个对象就会自动被销毁,那么,他对数据库的连接也就断开了。  
   
  用这个方法,每个用户可以有其自己的连接,即使若干用户同时发出对数据库的查询或存取,也都是通过其单独的连接,速度当然大大加快了。  
   
  在具体实现上,还需要写一个HttpSessionBindingListener,因为,当此用户登出你的网站时,你一定会写  
  session.invalidate();  
   
  于是,所有session里面的对象都销毁,包括conn,可是对数据库的连接还没断开。因此你要写一个class,实现interface   HttpSessionBindingListener;实现里面的public   void   valueBound(HttpSessionBindingEvent   event)和public   void   valueUnbound(HttpSessionBindingEvent   event)  
   
  当一个对象被绑定到session里面去时,valueBound()会自动被调用,当一个对象被session删掉或者session被销毁时,valueUnbound()会自动被调用。所以,你可以把断开数据库的语句放在valueUnbound()里面。例如  
   
  public   void   valueUnbound(HttpSessionBindingEvent   event)   {  
   
  try   {  
  if   (conn   !=   null)   {  
  conn.close();  
      }  
  }   catch   (SQLException   e)   {}  
  }  
   
  这样,当你的用户登出网站时,以上函数被调用,然后conn与数据库服务器断开。  
  下面是〈Java   Servlet   Programming〉里面的一个完整例子  
   
  import   java.io.*;  
  import   java.sql.*;  
  import   javax.servlet.*;  
  import   javax.servlet.http.*;  
   
  class   ConnectionHolder   implements   HttpSessionBindingListener   {  
      private   Connection   con   =   null;  
   
      public   ConnectionHolder(Connection   con)   {  
          //   Save   the   Connection  
          this.con   =   con;  
          try   {  
              con.setAutoCommit(false);     //   transactions   can   extend   between   web   pages!  
          }  
          catch(SQLException   e)   {  
              //   Perform   error   handling  
          }  
      }  
   
      public   Connection   getConnection()   {  
          return   con;     //   return   the   cargo  
      }  
   
      public   void   valueBound(HttpSessionBindingEvent   event)   {  
          //   Do   nothing   when   added   to   a   Session  
      }  
   
      public   void   valueUnbound(HttpSessionBindingEvent   event)   {  
          //   Roll   back   changes   when   removed   from   a   Session  
          //   (or   when   the   Session   expires)  
          try   {  
              if   (con   !=   null)   {  
                  con.rollback();     //   abandon   any   uncomitted   data  
                  con.close();  
              }  
          }  
          catch   (SQLException   e)   {  
              //   Report   it  
          }  
      }  
  }  
   
  /*   Actual   Servlet   */  
   
  public   class   ConnectionPerClient   extends   HttpServlet   {  
   
      public   void   init()   throws   ServletException   {  
          try   {  
              Class.forName("oracle.jdbc.driver.OracleDriver");  
          }  
          catch   (ClassNotFoundException   e)   {  
              throw   new   UnavailableException("Couldn't   load   OracleDriver");  
          }  
      }  
   
      public   void   doGet(HttpServletRequest   req,   HttpServletResponse   res)  
                                                                throws   ServletException,   IOException   {  
          res.setContentType("text/plain");  
          PrintWriter   out   =   res.getWriter();  
   
          HttpSession   session   =   req.getSession(true);  
          Connection   con;  
   
          //   Synchronize:   Without   this   two   holders   might   be   created   for   one   client  
          synchronized   (session)   {  
              //   Try   getting   the   connection   holder   for   this   client  
              ConnectionHolder   holder   =  
                  (ConnectionHolder)   session.getAttribute("servletapp.connection");  
   
              //   Create   (and   store)   a   new   connection   and   holder   if   necessary  
              if   (holder   ==   null)   {  
                  try   {  
                      holder   =   new   ConnectionHolder(DriverManager.getConnection(  
                          "jdbc:oracle:oci7:ordersdb",   "user",   "passwd"));  
                      session.setAttribute("servletapp.connection",   holder);  
                  }  
                  catch   (SQLException   e)   {  
                      log("Couldn't   get   db   connection",   e);  
                  }  
              }  
   
              //   Get   the   actual   connection   from   the   holder  
              con   =   holder.getConnection();  
          }  
   
          //   Now   use   the   connection  
          try   {  
              Statement   stmt   =   con.createStatement();  
              stmt.executeUpdate(  
                  "UPDATE   INVENTORY   SET   STOCK   =   (STOCK   -   10)   WHERE   PRODUCTID   =   7");  
              stmt.executeUpdate(  
                  "UPDATE   SHIPPING   SET   SHIPPED   =   (SHIPPED   +   10)   WHERE   PRODUCTID   =   7");  
   
              //   Charge   the   credit   card   and   commit   the   transaction   in   another   servlet  
              res.sendRedirect(res.encodeRedirectURL(  
                  req.getContextPath()   +   "/servlet/CreditCardHandler"));  
          }  
          catch   (Exception   e)   {  
              //   Any   error   is   grounds   for   rollback  
              try   {  
                  con.rollback();  
                  session.removeAttribute("servletapp.connection");  
              }  
              catch   (Exception   ignored)   {   }  
              out.println("Order   failed.   Please   contact   technical   support.");  
          }  
      }  
  }  
   
  Top

4 楼princerock(princeVC)回复于 2003-02-04 19:57:53 得分 0

upTop

相关问题

  • 数据库连接资源问题
  • 包含大量数据库的程序如何降低资源消耗?
  • 急!使用ado多次连接数据库会不断的消耗内存?!
  • 怎么连接数据库节省资源
  • 如果一个方法返回值是OleDbDataReader,怎样才能使其OleDbConnection(数据库连接)关闭?若是不关闭连接会消耗大量服务器资源吗??
  • 数据库连接
  • 连接数据库!!!
  • 连接数据库!!!
  • 数据库连接!
  • 数据库连接

关键词

  • 数据库
  • 连接
  • 用户
  • 查询
  • 系统
  • 网站
  • valueunbound
  • httpsessionbindingevent
  • 断开
  • 调用

得分解答快速导航

  • 帖主:princerock
  • dd777
  • yysinger
  • zhirenshao

相关链接

  • CSDN Java频道
  • Java类图书
  • Java类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
世纪乐知(北京)网络技术有限公司 版权所有, 京 ICP 证 020026 号
北京创新乐知广告有限公司 提供技术支持
Copyright © 2000-2007, CSDN.NET, All Rights Reserved
GongshangLogo