我讨厌提出一个在网络上被广泛询问的问题,但我似乎无法解决它。
我前段时间开始了一个项目,经过一个月的测试,我遇到了“连接太多”的错误。我调查了它,并通过增加 max_connections 来“解决”了它。这随后奏效了。
从那时起,越来越多的人开始使用它,它又火了起来。当我是站点上的唯一用户时,我键入“show processlist”,它会显示大约 50 个仍处于打开状态的连接(在命令中说“Sleep”)。现在,我不知道为什么这些是打开的,但在我的代码中我三重检查并且我打开的每个连接,我关闭。
即。
public int getSiteIdFromName(String name, String company)throws DataAccessException,java.sql.SQLException{
Connection conn = this.getSession().connection();
Statement smt = conn.createStatement();
ResultSet rs=null;
String query="SELECT id FROM site WHERE name='"+name+"' and company_id='"+company+"'";
rs=smt.executeQuery(query);
rs.next();
int id=rs.getInt("id");
rs.close();
smt.close();
conn.close();
return id;
}
每次我在网站上做其他事情时,都会打开而不是关闭另一负载的连接。 我的代码有问题吗?如果不是,可能是什么问题?
最佳答案
使用您的方法,如果在 调用 conn.close()
之前抛出任何异常,连接将永远不会关闭。您需要在 try
block 中获取它(以及语句和结果集)并在 finally
block 中关闭它。无论是否抛出异常,finally
中的任何代码都将始终 执行。有了它,您可以确保昂贵的资源将被关闭。
这里是一个重写:
public int getSiteIdFromName(String name, String company) throws DataAccessException, java.sql.SQLException {
Connection conn = null;
Statement smt = null;
ResultSet rs = null;
int id = 0;
try {
conn = this.getSession().connection();
smt = conn.createStatement();
String query = "SELECT id FROM site WHERE name='" + name + "' and company_id='" + company + "'";
rs = smt.executeQuery(query);
rs.next();
id = rs.getInt("id");
} finally {
if (rs != null) try { rs.close(); } catch (SQLException logOrIgnore) {}
if (smt != null) try { smt.close(); } catch (SQLException logOrIgnore) {}
if (conn != null) try { conn.close(); } catch (SQLException logOrIgnore) {}
}
return id;
}
也就是说,此代码对 SQL injection 敏感attacks .使用 PreparedStatement
而不是 Statement
。
另见:
关于java - MySql连接太多,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3069378/