jsp+tomcat+mysql 关于连接池 资源耗尽 高手进 大家试一下,很久没有解决啦。
连接BEAN:
//mysqltest.java
package news;
import java.sql.*;
import java.util.HashMap;
import javax.sql.*;
import javax.naming.*;
public class mysqltest
{
private static DataSource ds=null;
private static Connection conn= null;
Statement stmt = null;
PreparedStatement pstmt=null;
ResultSet rs = null;
public static DataSource localhost(){
//在HashMap中通过get()来获取value,通过put()来插入value,
//ContainsKey()则用来检验对象是否已经存在
HashMap <Object,Object> cachedDs=new HashMap <Object,Object> ();
if(cachedDs.containsKey( "ds "))//取出空闲状态的数据库连接
{
/* 在DataSource中事先建立了多个数据库连接,
* 这些数据库连接保存在连接池(Connect Pool)中。
* Java程序访问数据库时,只需要从连接池中取出空闲状态的数据库连接;
* 当程序访问数据库结束,再将数据库连接放回连接池。
* */
ds = (DataSource)cachedDs.get( "ds ");
}
else
try
{
/*在javax.naming包中提供了Context接口,
* 该接口提供了将对象和名字绑定,以及通过名字检索对象的方法。
* */
InitialContext initCtx = new InitialContext();
//lookup(String name):返回与指定的名字绑定的对象,获得数据库连接工厂
ds = (DataSource)initCtx.lookup( "java:comp/env/jdbc/jlpd ");
cachedDs.put( "ds ", ds);
}
catch(Exception e)
{
e.printStackTrace();
}
return ds;
}
//getConn
public static Connection getConn()
{
try
{
if( conn == null )
{
DataSource ds = localhost();
conn = ds.getConnection();
}
}
catch(Exception e)
{
System.err.println( "sql_data(): " + e.getMessage());
}
return conn;
}
//mysqltest
public mysqltest()
{}
//pstmt query
public PreparedStatement execute(String sql)
{
try
{
pstmt = getConn().prepareStatement(sql);
}
catch(SQLException ex)
{
System.err.println( "sql_data.executeUpdate: "+ex.getMessage());
}
return pstmt;
}
//insert
public void executeInsert(String sql)
{
try
{
stmt = getConn().createStatement();
stmt.executeUpdate(sql);
stmt.close();
stmt = null;
}
catch(SQLException ex)
{
System.err.println( "sql_data.executeUpdate: "+ex.getMessage());
}
}
//query
public ResultSet executeQuery(String sql)
{
try
{
stmt = getConn().createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery(sql);
}
catch(SQLException ex)
{
System.err.println( "sql_data.executeQuery: "+ex.getMessage());
}
return rs;
}
//update
public void executeUpdate(String sql)
{
try
{
stmt = getConn().createStatement();
stmt.executeUpdate(sql);
stmt.close();
stmt = null;
}
catch(SQLException ex)
{
System.err.println( "sql_data.executeUpdate: "+ex.getMessage());
}
}
//delete
public void executeDelete(String sql)
{
try
{
stmt = getConn().createStatement();
stmt.executeUpdate(sql);
stmt.close();
stmt = null;
}
catch(SQLException ex)
{
System.err.println( "sql_data.executeUpdate: "+ex.getMessage());
}
}
public void closeStmt()
{
try
{
if(stmt != null)
{
stmt.close();
stmt = null;
}
}
catch(SQLException e)
{
e.printStackTrace();
}
}
public void closeConn()
{
try
{
if(conn != null)
{
conn.close();
conn = null;
}
}
catch(SQLException e)
{
e.printStackTrace();
}
}
//close
public void closeDB()
{
try
{
if(stmt != null)
{
stmt.close();
stmt = null;
}
}
catch(SQLException e)
{
e.printStackTrace();
}
try
{
if(conn != null)
{
conn.close();
conn = null;
}
}
catch(SQLException e)
{
e.printStackTrace();
}
}
}
对于
public static Connection getConn()
{
try
{
if( conn == null )
{
DataSource ds = localhost();
conn = ds.getConnection();
}
}
catch(Exception e)
{
System.err.println( "sql_data(): " + e.getMessage());
}
return conn;
}
不管是用连接池还是用普通的连接,只要定义为静态的public static,再加上
if(conn==null)之后在调用连接,比普通的快几十倍。
不知道定义为静态的是否有什么弊端。最主要的问题就是:
mysql默认对8个小时没有任何操作的连接自动关闭。如何在jsp页面中没有加conn.close();的话,你刷新页面会连接失败。如果加了会正常运行。
但是如果你按F5一直刷新的话,对于前者正常,后者会出现连接错误。因为还没有关闭完的时候你再次连接就会出现问题。
我现在需要的就是:
不管是用tomcat连接池或者是普通的连接Bean,
1、当你按F5一直刷新的时候,运行正常,而且速度要快。
2、当mysql(默认8个小时,可以自己调为几分钟)自动断开其连接后,能正常自动连接。
如实现了,在开帖赠送分数。
[解决办法]
连接数据库是非常耗资源的 所以要尽量使用连接池 保持一定的连接数
如果要实现断开后自动连接 可以封装一个函数来取得可用连接 这个函数最先到连接池中取连接 然后判断取得的连接是否可用 如果取不到可用的连接 就重新建立连接 然后返回出去
使用连接池要注意 每次用过连接 要将其返回给连接池 否则会造成连接数超过上限
[解决办法]
学习了