使用 JDBC 获取与 MySQL 的连接时出现“连接过多”

Posted

技术标签:

【中文标题】使用 JDBC 获取与 MySQL 的连接时出现“连接过多”【英文标题】:"Too many Connections" when obtaining connection to MySQL using JDBC 【发布时间】:2014-05-28 16:10:24 【问题描述】:

尝试查询 mysql 数据库时遇到奇怪的问题;我在第一次调用 getConnection 时收到“连接过多”错误。我肯定在做一些愚蠢的事情吗?作为参考,我know the basics of closing connection,不仅我只打了一个电话,而且第一次尝试就失败了。所以我一定是在做一些非常愚蠢的事情?

两个类,一个调用查询,另一个执行查询: 导入 java.sql.*;

public class Main 

    public static void main(String[] args) 

        CollectorDb.findEvents();
    


public class CollectorDb 
    private static String username = "foo";
    private static String password = "bar";
    private static String connectionString = "jdbc:mysql://awsdb/dbName" +
            "?characterEncoding=UTF-8";

    public static void findEvents() 
        Connection conn = null;
        Statement stmt = null;
        ResultSet rset = null;

        try 
            Class.forName("com.mysql.jdbc.Driver");
        
        catch (ClassNotFoundException e) 
            e.printStackTrace();
        


        try 
            // Next line throws Exception
            conn = DriverManager.getConnection(connectionString, username, password);
            // ** NEVER GET HERE **
            // single query, then close all connections in a finally block
            ...
    


堆栈跟踪的第一行:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Too many connections
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:408)
...
Exception in thread "main" java.lang.RuntimeException: Too many connections
    at com.lifesize.CollectorDb.findEvents(CollectorDb.java:64)
    at com.lifesize.Main.main(Main.java:13)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
...

已经截断了我认为不相关的细节 - 很高兴提供更多代码或完整的堆栈跟踪,或者任何其他信息。

【问题讨论】:

这就是你调用 findEvents 的方式吗?只有一次? 您的代码在我看来是正确的(或者至少应该可以工作)。在任何情况下,错误都来自服务器。所以你可能想看看它是如何配置的,还有谁在连接到数据库。您可以尝试增加 my.cnf 中的连接数。 @SleimanJneidi 是的,只调用一次。 第一次尝试失败。 检查连接客户端的数量 SHOW STATUS WHERE variable_name = 'Threads_connected'; @chris 如果该程序的早期版本运行并且有旧连接挂在它周围,可能会导致您现在无法获得连接。登录数据库,显示进程列表;杀死连接。再试一次 【参考方案1】:

正如SleimanJneidi 和zmf 在cmets 中所指出的,问题根本不在于我的代码,而在于服务器本身;最大的线索是第一次尝试连接失败

在我的例子中,我没有直接访问服务器的权限,但是下面会显示当前连接的客户端:

SHOW STATUS WHERE variable_name = 'Threads_connected';

回答我的跟进“如果超过最大连接数,我如何连接以检查这个” - MySQL 为管理员保留连接,特别是出于这个原因.这可以在their documention找到:

允许的连接数由 max_connections 系统变量。默认值为 151 以提高 MySQL 与 Apache Web 服务器一起使用时的性能。 (以前,默认值为 100。)如果您需要支持更多 连接,你应该为这个变量设置一个更大的值。

mysqld 实际上允许 max_connections+1 个客户端进行连接。这 额外的连接保留给拥有 SUPER 的帐户使用 特权。通过授予管理员超级权限而不是 对于普通用户(不需要它),管理员可以连接 到服务器并使用 SHOW PROCESSLIST 来诊断问题,即使 连接的非特权客户端的最大数量。见部分 13.7.5.30,“显示 PROCESSLIST 语法”。

【讨论】:

【参考方案2】:

你必须放

                if(conn != null) 
                    try 
                    conn.close();   
                     catch (SQLException e) 
                        e.printStackTrace();
                    
                

【讨论】:

正如目前所写,您的答案尚不清楚。请edit 添加其他详细信息,以帮助其他人了解这如何解决所提出的问题。你可以找到更多关于如何写好答案的信息in the help center。

以上是关于使用 JDBC 获取与 MySQL 的连接时出现“连接过多”的主要内容,如果未能解决你的问题,请参考以下文章

使用 JDBC 连接器 5.1 从 Java 读取/写入 MySQL 中的 UTF-8 数据时出现问题

使用 JDBC 连接到 MySQL 数据库时出现问题

Java - 使用 JDBC 连接到在线 MySQL 数据库时出现问题

JDBC连接时出现的两个错误

使用MySQL练习增删改查时出现连接错误

尝试通过 JDBC 与 Postgres 建立 SSL 连接时出现 PSQLException“无法打开 SSL 根证书文件”