jsp中调用连接池的问题。

时间:2022-09-19 23:05:34
在servlet中调用连接池,会在servlet destroy时,执行连接池的release操作。
而jsp中没有,这样会发生连接池用户计数clients在jsp页面每刷新一次时都不断地增长。该怎么办?

5 个解决方案

#1


JSP实际是一个servlet,只不过其中输出的html代码复杂点罢了,DBConnectionManager 是连接池,下面的代码是jsp里的,也可以把它放到javabean里,看你的意思,用javabean的话不需要在jsp里建连接池,在bean里建连接池就可以了,在jsp里的到bean的数据就可以了。
<%
  //System.out.println(request.getParameter("list"));//链接参数由此传入
  DBConnectionManager connMgr = DBConnectionManager.getInstance();
  Connection con = connMgr.getConnection("idb");
  if (con == null) {
    out.println("不能获取数据库连接.");
    return;
  }

  ResultSet rs = null;

  Statement stmt = null;
  try {
    stmt = con.createStatement();
    rs = stmt.executeQuery("SELECT * FROM PROVINCE");

  }catch(Exception ee){ee.printStackTrace();}

%>

#2


你每次用完连接 就执行连接池的release操作 不就行了。

#3


可以手動release它呀!
在你的Bean裡可以加入一個方法去release,如下:
  public void close() throws SQLException{
if(stmt != null) stmt.close();
connMgr.freeConnection(connName,conn);
  }

#4


但是不是说jsp是变成servelet来执行的吗,二者怎么会有区别呢?

也就是说jsp会被编译成class像servlet一样来运行.

但是在servelt的destroy()中我们调用了release()方法.

但是jsp编译后生成的class的反编译后是这样的(resin2.1.6 -windows版)
    public void destroy()
    {
        _caucho_isDead = true;
        super.destroy();
    }
在这个里面它没有调用连接池的release()方法,这个与在servelet中不一样(少了release())
这就会导致clients计数不对.


to  pxq(风轻轻地吹) ;如果我在jsp中每次完成都调用release()的话,那连接池就起不到作用了,以为连接池管理着的release方法是这样的:
=============
连接池管理者:
public synchronized void release()
  {
    //等待直到最后一个客户程序调用
    if(--clients != 0)
    {
      return;
    }
    DBConnectionPool pool = null;
    Enumeration allPools = pools.elements();
    while(allPools.hasMoreElements())
    {
      pool = (DBConnectionPool) allPools.nextElement();
      pool.release();//这个方法写在下面
    }
    Driver driver = null;
    Enumeration allDrivers = drivers.elements();
    while(allDrivers.hasMoreElements())
    {
      driver = (Driver) allDrivers.nextElement();
      try
      {
        DriverManager.deregisterDriver(driver);
        //log("Deregistered JDBC driver " + driver.getClass().getName());
        log("撤销JDBC驱动程序 " + driver.getClass().getName()+"的注册");
      }
      catch(SQLException e)
      {
        //log(e, "Can not deregister JDBC driver: " + driver.getClass().getName());
        log(e, "无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName());
      }
    }
  }
===========
pool的release方法:

    public synchronized void release()
    {
      Enumeration allConnections = freeConnections.elements();
      while(allConnections.hasMoreElements())
      {
        Connection con = (Connection) allConnections.nextElement();
        try
        {
          con.close();
          //log("Closed connection for pool " + name);
          //log("关闭连接池" + name+"中的一个连接");
        }
        catch(SQLException e)
        {
          //log(e, "Can't close connection for pool " + name);
          log(e, "无法关闭连接池" + name+"中的连接");
        }
      }
      freeConnections.removeAllElements();
    }


也就是说我如何才能,把这个release的同样的功能加大jsp中像servlet一样呢?
--------
servelet中destroy()
代码:
  public void destroy()
  {
    connMgr.release();
    super.destroy();
  }

#5


我知道怎么搞了,呵呵,把它用jsp声明就可以了.这样数据库管理者就成了成员变量了,而不是局部变量了.

<%!
//声明变量,编译成servlet后成为成员变量.
%>

#1


JSP实际是一个servlet,只不过其中输出的html代码复杂点罢了,DBConnectionManager 是连接池,下面的代码是jsp里的,也可以把它放到javabean里,看你的意思,用javabean的话不需要在jsp里建连接池,在bean里建连接池就可以了,在jsp里的到bean的数据就可以了。
<%
  //System.out.println(request.getParameter("list"));//链接参数由此传入
  DBConnectionManager connMgr = DBConnectionManager.getInstance();
  Connection con = connMgr.getConnection("idb");
  if (con == null) {
    out.println("不能获取数据库连接.");
    return;
  }

  ResultSet rs = null;

  Statement stmt = null;
  try {
    stmt = con.createStatement();
    rs = stmt.executeQuery("SELECT * FROM PROVINCE");

  }catch(Exception ee){ee.printStackTrace();}

%>

#2


你每次用完连接 就执行连接池的release操作 不就行了。

#3


可以手動release它呀!
在你的Bean裡可以加入一個方法去release,如下:
  public void close() throws SQLException{
if(stmt != null) stmt.close();
connMgr.freeConnection(connName,conn);
  }

#4


但是不是说jsp是变成servelet来执行的吗,二者怎么会有区别呢?

也就是说jsp会被编译成class像servlet一样来运行.

但是在servelt的destroy()中我们调用了release()方法.

但是jsp编译后生成的class的反编译后是这样的(resin2.1.6 -windows版)
    public void destroy()
    {
        _caucho_isDead = true;
        super.destroy();
    }
在这个里面它没有调用连接池的release()方法,这个与在servelet中不一样(少了release())
这就会导致clients计数不对.


to  pxq(风轻轻地吹) ;如果我在jsp中每次完成都调用release()的话,那连接池就起不到作用了,以为连接池管理着的release方法是这样的:
=============
连接池管理者:
public synchronized void release()
  {
    //等待直到最后一个客户程序调用
    if(--clients != 0)
    {
      return;
    }
    DBConnectionPool pool = null;
    Enumeration allPools = pools.elements();
    while(allPools.hasMoreElements())
    {
      pool = (DBConnectionPool) allPools.nextElement();
      pool.release();//这个方法写在下面
    }
    Driver driver = null;
    Enumeration allDrivers = drivers.elements();
    while(allDrivers.hasMoreElements())
    {
      driver = (Driver) allDrivers.nextElement();
      try
      {
        DriverManager.deregisterDriver(driver);
        //log("Deregistered JDBC driver " + driver.getClass().getName());
        log("撤销JDBC驱动程序 " + driver.getClass().getName()+"的注册");
      }
      catch(SQLException e)
      {
        //log(e, "Can not deregister JDBC driver: " + driver.getClass().getName());
        log(e, "无法撤销下列JDBC驱动程序的注册: " + driver.getClass().getName());
      }
    }
  }
===========
pool的release方法:

    public synchronized void release()
    {
      Enumeration allConnections = freeConnections.elements();
      while(allConnections.hasMoreElements())
      {
        Connection con = (Connection) allConnections.nextElement();
        try
        {
          con.close();
          //log("Closed connection for pool " + name);
          //log("关闭连接池" + name+"中的一个连接");
        }
        catch(SQLException e)
        {
          //log(e, "Can't close connection for pool " + name);
          log(e, "无法关闭连接池" + name+"中的连接");
        }
      }
      freeConnections.removeAllElements();
    }


也就是说我如何才能,把这个release的同样的功能加大jsp中像servlet一样呢?
--------
servelet中destroy()
代码:
  public void destroy()
  {
    connMgr.release();
    super.destroy();
  }

#5


我知道怎么搞了,呵呵,把它用jsp声明就可以了.这样数据库管理者就成了成员变量了,而不是局部变量了.

<%!
//声明变量,编译成servlet后成为成员变量.
%>