现在我遇到这个的难题,采用的是连接池进行配置的。当同时在线操作的用户达到60多人左右,系统就非常的慢而且几乎在查询或者添加数据的时候要等好几分钟。我怀疑是不是连接没得到有效的释放。求高人指导下!package tl.common;
import java.sql.*;import tl.logs.MyLog;public class GetConnect {

private static GetConnect mycon=null;
private Connection con;

private void initConnect()
{

try {
Class.forName("org.logicalcobwebs.proxool.ProxoolDriver"); 
con=DriverManager.getConnection("proxool.oa");

} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
MyLog.log("GetConnect", "initConnect", e.getMessage());
}
}

public Connection getConnection()
{
initConnect();
if(con!=null)
return con;
else
return null;
}

public void closeConnection()
{
try
{
if(con!=null)
con.close();
if(mycon!=null)
mycon=null;
}catch(Exception e){
e.printStackTrace();
MyLog.log("GetConnect", "closeConnection", e.getMessage());
}
}
public void closeConnectionmycon()
{
try
{
if(con!=null)
con.close();
if(mycon!=null)
mycon=null;
}catch(Exception e){
e.printStackTrace();
MyLog.log("GetConnect", "closeConnectionmy", e.getMessage());
}
}
public static GetConnect getConnect()
{
if(mycon==null)
mycon=new GetConnect(); return mycon;
}}-------------------------------下面是另外一个使用的方法---------------------
public class OperationPES  extends SuperOperation{
private static OperationPES ope = null;
FileSyntheticType fs = new FileSyntheticType() ;
private PreparedStatement st ;
Connection conn ;
synchronized void close2() {
try {
if (rs != null)
rs.close();
if (stmt != null)
{
stmt.close();
stmt=null;
}
if(st!=null)
{
st.close() ;
st=null ;
}
if (pstmt != null)
{
pstmt.close();
pstmt=null ;
}
if (getcon != null)
{
getcon.closeConnectionmycon();
}

if(conn!=null)
{
conn.close() ;
}


} catch (Exception e) {
e.printStackTrace();
MyLog.log("Operation", "close", e.getMessage());
}
} private OperationPES() {
getcon = GetConnect.getConnect();
} public synchronized static OperationPES getOperation(HttpServletRequest request) {
if (ope == null)
ope = new OperationPES();
ope.setRequest(request);
return ope;
}
//根据用户身份证明查询出体检表
public synchronized ArrayList<Object[]> Show_tijian_list_bysfnumber(int pageId,int pagecount,String sfnumber) {
String sql=setSqlValue(SelectSqlPES.SHOW_TIJIAN_BYSFNUMBER, new String[]{pagecount+"",(pageId-1>0?(pageId-1)*pagecount:0)+"",sfnumber,sfnumber}, new int[]{ValueKind.INTEGER,ValueKind.INTEGER,ValueKind.STRING,ValueKind.STRING});
return getSelectArray(sql,pagecount);
} //添加头像图片
public Boolean addtoutp(Tj_toupic tp) throws IOException {
try {
String sql = "insert into Tj_toupic(sfnumber,pic,time,type) values (?,?,?,?)";  //存在另外TOUPIC数据库里
conn = getcon.getConnection();
st = conn.prepareStatement(sql);
st.setString(1, tp.getSfnumber()) ;
st.setBinaryStream(2, tp.getPic(), tp.getPic().available());
st.setString(3, tp.getTime()) ;
st.setString(4, tp.getType()) ;
st.executeUpdate();
close2();

} catch (Exception e) {
e.printStackTrace();
close2();
return false ;

return true ;
}
//添加双手图片
public Boolean addshoutp(Tj_handspic tp) throws IOException {
try {
String sql = "insert into Tj_handspic(sfnumber,pic,time) values (?,?,?)";  //存在另外TOUPIC数据库里
conn = getcon.getConnection();
st = conn.prepareStatement(sql);
st.setString(1, tp.getSfnumber()) ;
st.setBinaryStream(2, tp.getPic(), tp.getPic().available());
st.setString(3, tp.getTime()) ;
st.executeUpdate();
close2();

} catch (Exception e) {
// e.printStackTrace();
close2();
return false ;

return true ;
}
//根据身份证明号码查询头像并生成一张图片存放在服务器上
public String  ImageGeneration_Tou(String downpath,String toupicID ) {
try {
fs.creatNewDir(downpath) ;
String sql = "select pic from Tj_toupic where id=?";
conn=getcon.getConnection();
st=conn.prepareStatement(sql);
st.setString(1,toupicID);
rs = st.executeQuery();
String ids=toupicID;
if (rs.next())
{

read(downpath, ids+".jpg", rs.getBinaryStream("pic"));

}
close2();
return ids+".jpg";
} catch (SQLException e) {
// TODO Auto-generated catch block
close2();
e.printStackTrace();
}
finally
{
close2();
}

return null;
}
-------------------------另外一个程序需要用到的数据库连接---------------------------public class SuperOperation {
GetConnect getcon; Statement stmt; PreparedStatement pstmt; ResultSet rs; HttpSession session;

HttpServletRequest request; //关闭
protected synchronized void close() {
try {
if (rs != null)
rs.close();
if (stmt != null)
{
stmt.close();
stmt=null;
}
if (pstmt != null)
{
pstmt.close();
pstmt=null;
}
if (getcon != null)
getcon.closeConnection();
} catch (Exception e) {
e.printStackTrace();
MyLog.log("Operation", "close", e.getMessage());
}
} synchronized void setSession(HttpSession session) {
this.session = session;
}

synchronized void setRequest(HttpServletRequest request) {
this.request = request;
setSession(request.getSession());
}

synchronized void log(String method, Exception e) {
MyLog.log(this.getClass().getName(), method, e.getMessage());
} synchronized String toCap(String orign)
{
return (orign.substring(0, 1).toUpperCase())+orign.substring(1);
}
/**
 * 初始化数据连接,和结果集
 * @param sql
 */
public synchronized ResultSet initpstmtStatementAndResultSet(String sql)
{
try {
pstmt=getcon.getConnection().prepareStatement(sql);
rs = pstmt.executeQuery() ;


} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log("initStatement",e);
}
return rs;
}
synchronized void initStatementAndResultSet(String sql)
{
try {
stmt=getcon.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs=stmt.executeQuery(sql);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log("initStatement",e);
}
}
/**
 * 初始化连接
 *
 */
synchronized void initStatement()
{
try { stmt=getcon.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log("initStatement",e);
}
}

synchronized void initStatementAndResultSetForInsert(String tablename)
{
try {
stmt=getcon.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs=stmt.executeQuery("select * from "+tablename+" where id=-1");
rs.moveToInsertRow();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log("initStatement",e);
}
}
synchronized void initStatementAndResultSetForUpdate(String tablename,int id)
{
try {
stmt=getcon.getConnection().createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs=stmt.executeQuery("select * from "+tablename+" where id="+id);

} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
log("initStatement",e);
}
}

解决方案 »

  1.   

    GetConnect是个单例类,
    这个类有一个私有成员变量,private Connection con;
    这也就意味着,所有的数据库操作都共用此私有变量con.
    在程序里获取数据库连接是这样写的
    public Connection getConnection()
    {
      initConnect();
      if(con!=null)
          return con;
      else
          return null;
    }
    似乎好象每一次的getcon.getConnection()操作,都会产生一个新的数据库连接对象,并把这个对象赋值给唯一的私有变量con.
    我的疑问是,是不是存在这样一种可能,当产生一个新的连接的时候,那么旧的数据库连接,在还没来得及关闭时,就已经成为了游离对象,所以没有任何句柄能够操作它
    那它所包含的连接,就是没有关闭的
      

  2.   

    一般连接数据库的方法里,都是有try{}catch(){}finally{}结构。finally中在本方法内用到的新取得的对象。原则上都要close。象stmt等,能关的都关。而在外围一次数据库连接也同样需要在finally中关闭连接。
    只想到这些。