而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();}
%>
<%
//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);
}
在你的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();
}
也就是说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后成为成员变量.
%>
<%!
//声明变量,编译成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();}
%>
<%
//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);
}
在你的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();
}
也就是说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后成为成员变量.
%>
<%!
//声明变量,编译成servlet后成为成员变量.
%>