记录一次数据库连接池不关闭,导致的错误
·
今天我在写表单验证的时候,发现了一个离奇的问题,只要我尝试登陆超过一定次数,就会固定会出现阻塞
阻塞后,重启tomcat,总会一闪而过这些提示:
这些提示很明了了,说明是在Servlet中出现了阻塞,那我就在Servlet插桩试一下
我在Servlet前后都加上输出,可以看一下结果:
每次Servlet都可以被访问,但最后都出不来,那问题就出在Servlet里的代码了:
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("进入登录验证");
Map<String, String[]> params = req.getParameterMap();
User user = new User();
user.setName(params.get("userName")[0]);
user.setPassword(params.get("password")[0]);
boolean flag = userService.login(user);
if (flag) {
// 如果登录成功,将登陆信息存入session中
req.getSession().setAttribute("user",user);
System.out.println("session存值");
//登录成功,跳转到成功页面(转发)
req.getRequestDispatcher("success.jsp").forward(req,resp);
} else {
//登录失败,跳转到失败页面(重定向)
resp.sendRedirect("fail.jsp");
}
/**
* 这里发现一个问题,只要前端请求登录5次以上,马上就会出现阻塞
* 初步认为是数据库连接池的问题
*/
System.out.println("登录验证结束!");
System.out.println("\n\n");
}
这里只有可能是Service代码出的问题,我又往Service找:
public boolean login(User user) {
List<User> users = userDao.selectByName(user.getName());
//查无此人
if (users==null || users.size()==0) {
return false;
}
User daoUser = users.get(0);
//密码不匹配
if (!Objects.equals(user.getPassword(),daoUser.getPassword())) {
return false;
}
//匹配成功
return true;
}
因为这是一个测试项目,service层代码并不复杂,所以只可能是Dao层的问题:
@Override
public List<User> selectByName(String name) {
String sql = "select * from user where name =?";
ArrayList params = new ArrayList();
params.add(name);
ResultSet rs = this.query(sql, params);
List<User> users = ResultSetUtil.ResultSetToBean(rs, User.class);
// close();
return users;
}
@Override
public User selectById(Integer id) {
String sql = "select * from user where id =?";
ArrayList params = new ArrayList();
params.add(id);
ResultSet rs = this.query(sql, params);
List<User> users = ResultSetUtil.ResultSetToBean(rs, User.class);
if (users!=null && users.size()>0) {
return users.get(0);
}
// close();
return null;
}
@Override
public List<User> queryAll() {
String sql = "select * from user";
ResultSet res = query(sql, null);
List<User> users = ResultSetUtil.ResultSetToBean(res, User.class);
// close();
return users;
}
因为 JDBC 的操作,我用反射封装了,所以要在BaseDao中找:
这个时候我才意识到,自己写的 close()方法,从来没有用过
这个时候,我就开始思考,是不是因为自己从来没有返回数据库连接,使得前面的连接被占用,导致后面的请求,都无法使用连接?
于是,我乖乖的在Dao层实现中,加上了 close()方法的调用:

果然,在添加了连接池关闭操作后,现在无论请求多少次,都不会出现阻塞了!
更多推荐
所有评论(0)