Java/JDBC/MySQL:如何排除DriverManager.getConnection()返回NULL的原因?

Java/JDBC/MySQL:如何排除DriverManager.getConnection()返回NULL的原因?,java,mysql,jdbc,Java,Mysql,Jdbc,我试图解决一个Java应用程序的问题,该应用程序正在利用JDBC连接到MySQL数据库。表面问题是,连接到有效数据库时,DriverManager.getConnection有时会返回NULL,而几分钟后它会返回到完全相同的数据库的有效连接 我正试图解决这个问题,但我对Java、JDBC和MySQL在何处相遇的理解相当有限。我在这方面做了很多研究,但遇到了困难,不知道该怎么办 以下是我迄今为止所做的工作: 在Java端,我一直跟踪代码到DriverManager.getConnection()

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

我正试图解决这个问题,但我对Java、JDBC和MySQL在何处相遇的理解相当有限。我在这方面做了很多研究,但遇到了困难,不知道该怎么办

以下是我迄今为止所做的工作:

  • 在Java端,我一直跟踪代码到DriverManager.getConnection()。我已经确定空连接是从那里来的,但是我不知道getConnection引擎盖下发生了什么。我一直在努力在网上找到一个彻底的解释
  • 在MySQL端,我已经验证了我有很多可用的连接(有时大约有1000个免费连接),所以我知道我没有超过最大连接数。通过查看日志,我能够确定在我遇到最多问题的时间段内,有更多的连接被中止,但我不知道如何确定这些连接被中止的原因(MySQL中止了吗,JDBC,Java应用程序?)我不确定MySQL端是否还有其他需要查找的内容
  • 在中间,有了JDBC,我很迷茫。我一直在阅读MySQL Connector/J,但不确定这些信息是否与Java正在使用的JDBC驱动程序有关
如果您能告诉我今后的发展方向,我将不胜感激

谢谢

编辑-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);
    }

我认为代码实际上没有任何问题,而是getConnection()和MySQL之间的某个问题。

是的,
DriverManager
是为您获取连接的类

它使用您从MySQL Connector-J JAR获得的JDBC驱动程序类来管理这一点。启动时,该JAR必须位于
类路径中

首先确保您可以从运行Java应用程序的机器连接到MySQL。成功登录MySQL管理应用程序,您已经越过了第一个障碍

我会根据你的情况给你上一堂医生课。这些方法通常对您有用。根据您的情况修改连接、凭据和查询,然后重试。我知道这个代码是有效的

package persistence;

import java.sql.*;
import java.util.*;

/**
 * util.DatabaseUtils
 * User: Michael
 * Date: Aug 17, 2010
 * Time: 7:58:02 PM
 */
public class DatabaseUtils {
/*
    private static final String DEFAULT_DRIVER = "oracle.jdbc.driver.OracleDriver";
    private static final String DEFAULT_URL = "jdbc:oracle:thin:@host:1521:database";
    private static final String DEFAULT_USERNAME = "username";
    private static final String DEFAULT_PASSWORD = "password";
*/
/*
    private static final String DEFAULT_DRIVER = "org.postgresql.Driver";
    private static final String DEFAULT_URL = "jdbc:postgresql://localhost:5432/party";
    private static final String DEFAULT_USERNAME = "pgsuper";
    private static final String DEFAULT_PASSWORD = "pgsuper";
*/
    private static final String DEFAULT_DRIVER = "com.mysql.jdbc.Driver";
    private static final String DEFAULT_URL = "jdbc:mysql://localhost:3306/party";
    private static final String DEFAULT_USERNAME = "party";
    private static final String DEFAULT_PASSWORD = "party";

    public static void main(String[] args) {
        long begTime = System.currentTimeMillis();

        String driver = ((args.length > 0) ? args[0] : DEFAULT_DRIVER);
        String url = ((args.length > 1) ? args[1] : DEFAULT_URL);
        String username = ((args.length > 2) ? args[2] : DEFAULT_USERNAME);
        String password = ((args.length > 3) ? args[3] : DEFAULT_PASSWORD);

        Connection connection = null;

        try {
            connection = createConnection(driver, url, username, password);
            DatabaseMetaData meta = connection.getMetaData();
            System.out.println(meta.getDatabaseProductName());
            System.out.println(meta.getDatabaseProductVersion());

            String sqlQuery = "SELECT PERSON_ID, FIRST_NAME, LAST_NAME FROM PERSON ORDER BY LAST_NAME";
            System.out.println("before insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST));

            connection.setAutoCommit(false);
            String sqlUpdate = "INSERT INTO PERSON(FIRST_NAME, LAST_NAME) VALUES(?,?)";
            List parameters = Arrays.asList("Foo", "Bar");
            int numRowsUpdated = update(connection, sqlUpdate, parameters);
            connection.commit();

            System.out.println("# rows inserted: " + numRowsUpdated);
            System.out.println("after insert: " + query(connection, sqlQuery, Collections.EMPTY_LIST));
        } catch (Exception e) {
            rollback(connection);
            e.printStackTrace();
        } finally {
            close(connection);
            long endTime = System.currentTimeMillis();
            System.out.println("wall time: " + (endTime - begTime) + " ms");
        }
    }

    public static Connection createConnection(String driver, String url, String username, String password) throws ClassNotFoundException, SQLException {
        Class.forName(driver);
        if ((username == null) || (password == null) || (username.trim().length() == 0) || (password.trim().length() == 0)) {
            return DriverManager.getConnection(url);
        } else {
            return DriverManager.getConnection(url, username, password);
        }
    }

    public static void close(Connection connection) {
        try {
            if (connection != null) {
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


    public static void close(Statement st) {
        try {
            if (st != null) {
                st.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void close(ResultSet rs) {
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static void rollback(Connection connection) {
        try {
            if (connection != null) {
                connection.rollback();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    public static List<Map<String, Object>> map(ResultSet rs) throws SQLException {
        List<Map<String, Object>> results = new ArrayList<Map<String, Object>>();
        try {
            if (rs != null) {
                ResultSetMetaData meta = rs.getMetaData();
                int numColumns = meta.getColumnCount();
                while (rs.next()) {
                    Map<String, Object> row = new HashMap<String, Object>();
                    for (int i = 1; i <= numColumns; ++i) {
                        String name = meta.getColumnName(i);
                        Object value = rs.getObject(i);
                        row.put(name, value);
                    }
                    results.add(row);
                }
            }
        } finally {
            close(rs);
        }
        return results;
    }

    public static List<Map<String, Object>> query(Connection connection, String sql, List<Object> parameters) throws SQLException {
        List<Map<String, Object>> results = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = connection.prepareStatement(sql);

            int i = 0;
            for (Object parameter : parameters) {
                ps.setObject(++i, parameter);
            }
            rs = ps.executeQuery();
            results = map(rs);
        } finally {
            close(rs);
            close(ps);
        }
        return results;
    }

    public static int update(Connection connection, String sql, List<Object> parameters) throws SQLException {
        int numRowsUpdated = 0;
        PreparedStatement ps = null;
        try {
            ps = connection.prepareStatement(sql);

            int i = 0;
            for (Object parameter : parameters) {
                ps.setObject(++i, parameter);
            }
            numRowsUpdated = ps.executeUpdate();
        } finally {
            close(ps);
        }
        return numRowsUpdated;
    }
}
包持久化;
导入java.sql.*;
导入java.util.*;
/**
*util.DatabaseUtils
*用户:迈克尔
*日期:2010年8月17日
*时间:下午7:58:02
*/
公共类数据库{
/*
私有静态最终字符串DEFAULT_DRIVER=“oracle.jdbc.DRIVER.OracleDriver”;
私有静态最终字符串DEFAULT_URL=“jdbc:oracle:thin:@host:1521:database”;
私有静态最终字符串默认值\u USERNAME=“USERNAME”;
私有静态最终字符串DEFAULT_PASSWORD=“PASSWORD”;
*/
/*
私有静态最终字符串DEFAULT_DRIVER=“org.postgresql.DRIVER”;
私有静态最终字符串DEFAULT\u URL=“jdbc:postgresql://localhost:5432/party";
私有静态最终字符串默认值\u USERNAME=“pgsuper”;
私有静态最终字符串DEFAULT_PASSWORD=“pgsuper”;
*/
私有静态最终字符串DEFAULT_DRIVER=“com.mysql.jdbc.DRIVER”;
私有静态最终字符串DEFAULT\u URL=“jdbc:mysql://localhost:3306/party";
私有静态最终字符串默认值\u USERNAME=“party”;
私有静态最终字符串DEFAULT_PASSWORD=“party”;
公共静态void main(字符串[]args){
long begTime=System.currentTimeMillis();
字符串驱动程序=((args.length>0)?args[0]:默认_驱动程序);
字符串url=((args.length>1)?args[1]:默认url);
字符串用户名=((args.length>2)?args[2]:默认用户名);
字符串密码=((args.length>3)?args[3]:默认密码);
连接=空;
试一试{
connection=createConnection(驱动程序、url、用户名、密码);
DatabaseMetaData meta=connection.getMetaData();
System.out.println(meta.getDatabaseProductName());
System.out.println(meta.getDatabaseProductVersion());
String sqlQuery=“按姓氏从人员订单中选择人员ID、姓名、姓氏”;
System.out.println(“插入之前:+query(connection,sqlQuery,Collections.EMPTY_LIST));
connection.setAutoCommit(false);
String sqlUpdate=“插入个人(名字、姓氏)值(?,)”;
列表参数=Arrays.asList(“Foo”、“Bar”);
int numRowsUpdated=update(连接、sqlUpdate、参数);
commit();
System.out.println(“#插入行:“+numRowsUpdated”);
System.out.println(“插入后:+query(connection,sqlQuery,Collections.EMPTY_LIST));
}捕获(例外e){
回滚(连接);
e、 printStackTrace();
}最后{
关闭(连接);
long-endTime=System.currentTimeMillis();
System.out.println(“墙时间:”+(endTime-begTime)+“毫秒”);
}
}
公共静态连接createConnection(字符串驱动程序、字符串url、字符串用户名、字符串密码)抛出ClassNotFoundException,
java -classpath .;<Connector-J driver path here> persistence.DatabaseUtils
//  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");
}