Java/JDBC/MySQL:如何解决为什么DriverManager.getConnection()返回NULL?

TAC*_*EON 5 java mysql jdbc

我正在尝试解决使用JDBC连接到MySQL数据库的Java应用程序的问题.表面问题是,当连接到有效的数据库时,DriverManager.getConnection有时会返回NULL,而几分钟后它将返回到完全相同的数据库的有效连接.

我正在尝试解决这个问题,但我对Java,JDBC和MySQL相遇的理解相当有限.我一直在做很多关于这方面的研究,但已经撞墙了,不知道从哪里开始.

这是我到目前为止所做的:

  • 在Java端,我已经将代码一直跟踪到DriverManager.getConnection().我已经确定NULL连接来自那里,但我不知道getConnection引擎盖下发生了什么.我一直在努力在网上找到对此的详尽解释.
  • 在MySQL端,我已经确认有很多可用的连接(有时大约有1000个免费连接),所以我知道我没有超过那里的最大连接数.查看日志,我能够确定在我遇到最多问题的时间范围内中断的连接数略多,但我不知道如何确定为什么这些连接被中止(做了MySQL) abort,JDBC,Java应用程序?)我不确定在MySQL端还有什么我需要寻找的东西.
  • 在中间,使用JDBC,我很丢失.我一直在http://dev.mysql.com/doc/refman/5.1/en/connector-j.html上阅读MySQL Connector/J ,但我不确定该信息是否与正在使用的JDBC驱动程序有关. Java的.

任何关于我可以从这里离开的方向都将非常感激.

谢谢!

编辑 - 2月15日,美国中部时间上午10点35分 我为不具体而道歉.此应用程序是一个通常工作正常的生产应用程序.它成功处理了成千上万的连接,没有任何问题,只是这个问题会在白天随机出现,并且会在30秒到5分钟之间持续发生.

这是我一直追溯到DriverManager.getConnection的代码:

var dbConn = DatabaseConnectionFactory.createDatabaseConnection('com.mysql.jdbc.Driver','jdbc:mysql://'+ serverName +':' + port + '/' + database, userName, password);

public static DatabaseConnection createDatabaseConnection(String driver, String address, String username, String password) throws SQLException {
        try {
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }

        Properties info = new Properties();
        info.setProperty("user", username);
        info.setProperty("password", password);

        // this property should only be set if it's for embedded database
        info.setProperty("shutdown", "true");

        return new DatabaseConnection(address, info);
    }

public DatabaseConnection(String address, Properties info) throws SQLException {
        logger.debug("creating new database connection: address=" + address + ", " + info);
        this.address = address;
        connection = DriverManager.getConnection(address, info);
    }
Run Code Online (Sandbox Code Playgroud)

我不相信代码实际上有任何问题,而是getConnection()和MySQL之间的某个问题.

Mar*_*eel 7

单个驱动程序可以为连接请求返回null,JDBC 4.1规范说:

当DriverManager尝试建立连接时,它会调用该驱动程序的connect方法并将驱动程序传递给URL.如果Driver实现了解URL,则它将返回Connection对象,或者如果无法将连接发送到数据库,则抛出SQLException.如果Driver实现不理解URL,它将返回null.

然而,在看的代码java.sql.DriverManager(在Java 7中更新13),它会永远抛出一个SQLException带有消息发现<链接>没有合适的驱动程序时,所有可用驱动程序已经返回nullconnect(url, properties)电话:

//  Worker method called by the public getConnection() methods.
private static Connection getConnection(
    String url, java.util.Properties info, ClassLoader callerCL) throws SQLException {
// Removed some classloading stuff for brevity
    if(url == null) {
        throw new SQLException("The url cannot be null", "08001");
    }
    // Walk through the loaded registeredDrivers attempting to make a connection.
    // Remember the first exception that gets raised so we can reraise it.
    SQLException reason = null;
    for(DriverInfo aDriver : registeredDrivers) {
        // If the caller does not have permission to load the driver then
        // skip it.
        if(isDriverAllowed(aDriver.driver, callerCL)) {
            try {
                println("    trying " + aDriver.driver.getClass().getName());
                Connection con = aDriver.driver.connect(url, info);
                if (con != null) {
                    // Success!
                    println("getConnection returning " + aDriver.driver.getClass().getName());
                    return (con);
                }
            } catch (SQLException ex) {
                if (reason == null) {
                    reason = ex;
                }
            }
        } else {
            println("    skipping: " + aDriver.getClass().getName());
        }
    }
    // if we got here nobody could connect.
    if (reason != null)    {
        println("getConnection failed: " + reason);
        throw reason;
    }
    println("getConnection: no suitable driver found for "+ url);
    throw new SQLException("No suitable driver found for "+ url, "08001");
}
Run Code Online (Sandbox Code Playgroud)

换句话说:您所描述的内容不会发生(至少在Java 7 Update 13中不会发生).快速浏览Java 5 Update 22源代码显示几乎相同的实现,它根本无法返回null.

您更有可能吞下异常,然后尝试使用Connection值为null 的变量或字段.

另一种可能性是你没有获得连接DriverManager.getConnection(url, ...),但由于上面建立的规则,你DriverManager.getDriver(url).connect(...)可以返回连接null.如果你这样做,它可能指向Connector/J驱动程序中的错误,如果你总是使用完全相同的URL:驱动程序无法决定在某一点返回特定URL的连接,然后返回null.它应该总是返回一个Connection或抛出一个SQLException相同的URL.

  • 感谢您澄清它永远不会返回NULL,而是一个异常.我做了一些挖掘,发现了异常被吞噬的地方.我已经多次完成所有代码,我不确定我是如何错过它的. (2认同)