我已经知道数据库连接应该毫无疑问地关闭,我甚至可以理解为什么:
com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
这里是抛出上述异常的代码(在我的机器上):
public static void main(String[] args) {
try {
for (int i = 0; i < 1000; i++) {
Connection connection = getConnection();
Statement st = connection.createStatement();
st.execute("CREATE TABLE IF NOT EXISTS clients (id INT NOT NULL AUTO_INCREMENT, firstname VARCHAR(50), lastname VARCHAR(50), PRIMARY KEY (id))");
st.execute("DROP TABLE clients");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
private static Connection getConnection() throws SQLException {
return DriverManager.getConnection(bundle.getString("jdbc.url"),
bundle.getString("jdbc.username"), bundle.getString("jdbc.password"));
}
最终我不得不减少堆大小,上面的代码开始工作。在这些情况下发生了什么?如何在没有任何例外的情况下连续创建连接?
答案 0 :(得分:2)
我有根据的猜测是底层连接类已经实现了finalize()
方法,该方法在对象为GC时清理连接。
如果堆积较大,GC就不会那么努力,所以连接不会被收集。对于较小的堆,GC需要更频繁地收集它们,并且活动连接的限制不会达到最大值。
正确的方法是使用连接数量有限的连接池,这些连接始终保持打开状态,只需从池中借用并返回池中即可。毕竟创建连接是很昂贵的。