使用BoneCP连接池出现异常 内存泄露

joyrising 2013-10-19 11:04:54
使用BoneCP连接池,出现了“BoneCP detected an unclosed connection (in pool '***pool') and will now attempt to close it for you. You should be closing this connection in your application - enable connectionWatch for additional debugging assistance.”的异常。
我是在Tomcat中配置了JNDI,然后每次查询数据库时用下面两个类SqlConnection和SqlConnection来实现:
package db;

import java.sql.Connection;
import java.sql.SQLException;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import javax.sql.DataSource;
import com.mysql.jdbc.*;
/*
*使用数据库连接池,具体配置在%catalinahome%/conf/sever.xml的<context><resource>节点中
*/
public class SqlConnection {
private DataSource ds = null;
Connection conn =null;
public SqlConnection(){
//通过JNDI获得数据源
try {
InitialContext ctx=null;
ctx = new InitialContext();
ds=(DataSource)ctx.lookup("java:comp/env/jdbc/lxtjngJNDI");
} catch (NamingException e) {
e.printStackTrace();
}
}

public Connection getConnection() {
try{
return conn=ds.getConnection();
}catch(Exception ex){
System.out.print("数据库连接池初始化异常,信息是:"+ex.getMessage());
ex.printStackTrace();
return null;
}
}
// /////////////////////////////////////////////////////////////////////////////
/**
* 关闭连接
*/
public void close() {
try {
if (conn != null) {
conn.close();
conn = null;
}
} catch (SQLException se) {
System.out.println("close error: " + se.getMessage());
}
finally {
// Always make sure result sets and statements are closed,
// and the connection is returned to the pool

if (conn != null) {
try { conn.close(); } catch (SQLException e) {e.printStackTrace(); }
conn = null;
}
}

}

}
//////另一个类////////////////////////////////////////
package db;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SqlExe {
ResultSet rs =null;
Statement stmt=null;
int count = 0;// 结果记录集中记录条数
String errorMsg = "";
public SqlExe() {

}

// 执行查询语句的函数
// para sql:数据库查询语句体sql
// return ResultSet
public ResultSet executeQuery(String sql,Connection conn) {
try{
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
rs = stmt.executeQuery(sql);

}
catch(SQLException ex){
System.err.println("数据库查询失败in db.executeQuery: sql="+sql +"\r\n"+ ex.getMessage());
this.errorMsg = "查询数据失败!sql="+sql +"\r\n"+ ex.getMessage();
this.close();
}
return rs;
}

// /////////////////////////////////////////////////////////////////////////

/*----------执行数据库更改(增加、删除、替换)操作,返回boolean,表示是否更改成功--------------------///

*/
public boolean executeUpdate(String sql,Connection conn) {
boolean bupdate = false;
rs = null;
try {
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
int rowCount = stmt.executeUpdate(sql);// 如果不成功,bupdate就会返回0
if (rowCount != 0) {
bupdate = true;
this.count = rowCount;
}
} catch (SQLException ex) {
System.err.println("数据库更新db.executeUpdate失败: sql="+sql +"\r\n"+ ex.getMessage());
this.errorMsg = "查询数据失败!sql="+sql +"\r\n"+ ex.getMessage();
this.close();
this.count =-1;
}
/*finally{
this.close();
}*/
return bupdate;
}

/*-----------------------执行数据库更改(增加、删除、替换)操作,返回所操作的行数------------------------///

*/
public int exeUpdate(String sql,Connection conn, String errorMsg) {

rs = null;
try {
stmt = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_UPDATABLE);
int rowCount = stmt.executeUpdate(sql);
return this.count = rowCount;
} catch (SQLException ex) {// 如果不成功,bupdate就会返回-1
System.err.println("数据库更新db.executeUpdate失败: sql="+sql+"\r\n"+ ex.getMessage());
this.close();
if (errorMsg == null || errorMsg.length() == 0) {
this.errorMsg = "查询数据失败!sql="+sql +"\r\n"+ ex.getMessage();
} else
this.errorMsg = errorMsg;
return this.count =-1;
}
/*finally{
this.close();
}
*/
}

// /////////////////////////////////////////////////////////////////////////////
/**
* 关闭连接
*/
public void close() {
try {
if (rs != null) {
rs.close();
rs = null;
}
if (stmt != null) {
stmt.close();
stmt = null;
}
} catch (SQLException se) {
System.out.println("close error: " + se.getMessage());
} finally {
if (rs != null) {
try { rs.close(); } catch (SQLException e) { ; }
rs = null;
}
if (stmt != null) {
try { stmt.close(); } catch (SQLException e) { ; }
stmt = null;
}
}
}
}
/////////////////////////////////////////////////////
下面是调用这两个类来实现数据库查询
Connection conn = new SqlConnection().getConnection();
SqlExe sqlExe = new SqlExe();
if (null != conn) {
ResultSet rsGg=sqlExe.executeQuery(sql,conn);
​if(rsGg.next()){
out.print(rsGg.getString("code"));}
else{
out.print("广告burnmeSec950-90-1");
}
rsGg.close();
}
sqlExe.close();conn.close();
/////////////////////////////////////////
从调用来看,我关闭了ResultSet,Statement和Connection对象,但是BoneCp提示我有未关闭的连接,并且程序运行非常缓慢,占用内存非常高,最终宕机。
请教高手,我的做法哪里错了,为什么存在内存泄露?最好指出具体语句或方法,以及该如何改正,谢谢!
祥见百度空间http://hi.baidu.com/joyrising899
...全文
174 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

62,614

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧