我正在尝试解决使用JDBC连接到MySQL数据库的Java应用程序的问题.表面问题是,当连接到有效的数据库时,DriverManager.getConnection有时会返回NULL,而几分钟后它将返回到完全相同的数据库的有效连接.
我正在尝试解决这个问题,但我对Java,JDBC和MySQL相遇的理解相当有限.我一直在做很多关于这方面的研究,但已经撞墙了,不知道从哪里开始.
这是我到目前为止所做的:
任何关于我可以从这里离开的方向都将非常感激.
谢谢!
编辑 - 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之间的某个问题.
单个驱动程序可以为连接请求返回null,JDBC 4.1规范说:
当DriverManager尝试建立连接时,它会调用该驱动程序的connect方法并将驱动程序传递给URL.如果Driver实现了解URL,则它将返回Connection对象,或者如果无法将连接发送到数据库,则抛出SQLException.如果Driver实现不理解URL,它将返回null.
然而,在看的代码java.sql.DriverManager
(在Java 7中更新13),它会永远抛出一个SQLException
带有消息发现<链接>没有合适的驱动程序时,所有可用驱动程序已经返回null
了connect(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.