我正在尝试使用连接池库连接到我的数据库:DBPool.这是我的源代码.
package DB;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.sql.ConnectionPoolDataSource;
import snaq.db.ConnectionPool;
import com.mysql.jdbc.Driver;
/**
* @author decorrea
*/
public class DBUtils {
public static String jdbc_driver_name = "com.mysql.jdbc.Driver";
private static String server_name ;
private static String database;
private static String username;
private static String password;
public String getServer_name() {
return server_name;
}
public void setServer_name(String serverName) {
server_name = serverName;
}
public String getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
/*
* Creates a MySQL DB connection from a pool
*/
public Connection createConnection(ConnectionPool pool){
Connection connection = null;
try {
// Load the JDBC driver
Class driver_class = Class.forName(jdbc_driver_name);
Driver driver = (Driver)driver_class.newInstance();
DriverManager.registerDriver(driver);
connection = pool.getConnection();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return connection;
}
/*
* Creates a MySQL DB connection
*/
public Connection createConnection(){
Connection connection = null;
try {
// Load the JDBC driver
Class driver_class = Class.forName(jdbc_driver_name);
Driver driver = (Driver)driver_class.newInstance();
DriverManager.registerDriver(driver);
String url = "jdbc:mysql://" + server_name + "/" + database;
connection = DriverManager.getConnection(url);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
return connection;
}
}
Run Code Online (Sandbox Code Playgroud)
/**
* @author decorrea
*/
public class TwitterAPI {
private static String server_name = "127.0.0.1";
private static String twitter_databse = "twitter";
private static String username = "root";
private static String password = "password";
public static Connection startDBConnection(String server_name, String database, String username, String password) {
//Set DB parameters
DBUtils mysql_obj = setDBParams(server_name, database, username, password);
String url = "jdbc:mysql://" + server_name + "/" + database;
ConnectionPool pool = new ConnectionPool("local",1, 1, 1, 180000, url, username, password);
Connection connection = mysql_obj.createConnection(pool);
return connection;
}
public static DBUtils setDBParams(String server_name, String database, String username, String password){
DBUtils mysql_obj = new DBUtils();
mysql_obj.setServer_name(server_name);
mysql_obj.setDatabase(database);
mysql_obj.setUsername(username);
mysql_obj.setPassword(password);
return mysql_obj;
}
public static String getTweets(BigInteger id){
Connection connection = startDBConnection(server_name,twitter_databse,username,password);
ResultSet resultSet = null;
String tweet = new String();
try {
Statement statement = connection.createStatement();
String query = SQL_queries.get_tweets_on_id + id.toString();
//Execute the query
resultSet = statement.executeQuery(query);
while(resultSet.next()){
tweet = resultSet.getString("content");
}
resultSet.close();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
finally{
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return tweet;
}
}
Run Code Online (Sandbox Code Playgroud)
我是连接池业务的新手,并且决定这样做只是因为我没有收到"通信链路故障".
更新1:要添加我还尝试了Apache DBCP并尝试了此示例但仍然收到相同的错误.
org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Data source rejected establishment of connection, message from server: "Too many connections")
at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)
at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388)
at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
at Twitter.TwitterAPI.startDBConnection(TwitterAPI.java:55)
at Twitter.TwitterAPI.getTweets(TwitterAPI.java:84)
at Twitter.TwitterAPI.main(TwitterAPI.java:235)
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Data source rejected establishment of connection, message from server: "Too many connections"
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:45)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:528)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.Util.getInstance(Util.java:384)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1015)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:989)
at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:984)
at com.mysql.jdbc.MysqlIO.doHandshake(MysqlIO.java:1105)
at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2186)
at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:787)
at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:49)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:45)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:528)
at com.mysql.jdbc.Util.handleNewInstance(Util.java:409)
at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:357)
at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:285)
at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)
at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556)
at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545)
... 5 more
Exception in thread "main" java.lang.NullPointerException
at Twitter.TwitterAPI.getTweets(TwitterAPI.java:108)
at Twitter.TwitterAPI.main(TwitterAPI.java:235)
Run Code Online (Sandbox Code Playgroud)
我还检查了MySQL中my.ini文件中的max_connections变量.这是它的价值:
MySQL服务器允许的最大并发会话数.其中一个连接将保留给具有SUPER权限的用户,即使已达到连接限制,也允许管理员登录.
max_connections=100
的SHOW PROCESSLIST MySQL的终端上的命令显示在睡眠101个处理.
任何形式的帮助/评论将不胜感激
更新2 - 解决方案:: 所以,我找到了解决方案.我没有在数据库的url连接中提到端口名称.
String url = "jdbc:mysql://" + server_name + "/" + database;
Run Code Online (Sandbox Code Playgroud)
可能因此导致许多泄漏的联系.完成后,我尝试了这里给出的例子.它现在不会抛出任何错误.感谢BalusC,我认为这只是因为他对改变MySQL端口号的评论.要添加,更改MySQL端口号的方法不是通过更改my.ini文件,而是通过运行MySQL实例配置向导下开始- >程序- > MySQL服务器5.1 - > MySQL服务器实例配置向导.值得注意的是,当未指定端口号并且程序运行顺利时,代码没有抛出任何错误.也许,JDBC默认连接到3306.如果有人对此有任何特别的想法,请分享.
有关我的完整源代码,请参阅下面的答案
org.apache.commons.dbcp.SQLNestedException:无法创建PoolableConnectionFactory(数据源拒绝建立连接,来自服务器的消息:“连接太多”)
这表明,一些被泄露的连接。也就是说,某些东西会不断获取(打开)连接,而无需关闭它们和/或返回连接池。重新启动数据库,以便它可以硬关闭所有打开的连接,应该暂时解决此问题。修复某些问题,以便在使用后正确关闭连接,应可以永久解决此问题。
尽管发布的JDBC代码没有遵循最佳习惯用法,但它看起来并不是造成连接泄漏的原因。数据库可能已经运行了数小时/天,并且您在较早的测试中获得了太多的连接而没有关闭它们,因此数据库用尽了它们。
所以,我想出了解决办法。我没有在数据库连接的 url 中提到端口名称。
String url = "jdbc:mysql://" + server_name + "/" + database;
Run Code Online (Sandbox Code Playgroud)
可能因此导致了许多连接泄漏。完成后,我尝试使用此处给出的示例。现在它不会抛出任何错误。感谢 BalusC,我只是因为他对更改 MySQL 端口号的评论而发现了这一点。补充一下,更改MySQL端口号的方法不是通过更改my.ini文件,而是通过在“开始”->“程序”->“MySQL Server 5.1”->“MySQL服务器实例配置向导”下运行MySQL实例配置向导。有趣的是,当未指定端口号时,代码不会抛出任何错误,并且程序运行顺利。JDBC 可能默认连接到 3306。如果有人对此有任何特别的想法,请分享。
为了大家的利益,这里是源代码:
DBUtils.java
package DB;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSource;
import com.mysql.jdbc.Driver;
/**
* @author decorrea
*
*/
public class DBUtils {
public static String jdbc_driver_name = "com.mysql.jdbc.Driver";
private static String server_name ;
private static String database;
private static String username;
private static String password;
private static int maxActive = 20;
private static int maxIdle = 2 ;
public String getServer_name() {
return server_name;
}
public void setServer_name(String serverName) {
server_name = serverName;
}
public String getDatabase() {
return database;
}
public void setDatabase(String database) {
this.database = database;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public static DataSource getDataSource(String server_name, String database, String username, String password){
BasicDataSource datasource = new BasicDataSource();
datasource.setDriverClassName(jdbc_driver_name);
String url = "jdbc:mysql://" + server_name + "/" + database;
System.out.println(url);
datasource.setUsername(username);
datasource.setPassword(password);
datasource.setUrl(url);
datasource.setMaxActive(maxActive);
datasource.setMaxIdle(maxIdle);
return datasource;
}
}
Run Code Online (Sandbox Code Playgroud)
TwitterAPI.java
public class TwitterAPI {
private static String server_name = "localhost:7777";
private static String twitter_databse = "twitter";
private static String username = "root";
private static String password = "password";
public static String twitter_unique_usernames_file = "twitter_unique_usernames_file.txt";
public static String language_model_file = "C:\\de\\JARS\\lingpipe-4.0.0\\demos\\models\\langid-leipzig.classifier";
public static DataSource dataSource = DBUtils.getDataSource(server_name, twitter_databse, username, password);
public static Connection startDBConnection(String server_name, String database, String username, String password) {
//Set DB parameters
//DBUtils mysql_obj = setDBParams(server_name, database, username, password);
Connection connection = null;
//connection = mysql_obj.createConnection();
try {
connection = dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
}
return connection;
}
public static DBUtils setDBParams(String server_name, String database, String username, String password){
DBUtils mysql_obj = new DBUtils();
mysql_obj.setServer_name(server_name);
mysql_obj.setDatabase(database);
mysql_obj.setUsername(username);
mysql_obj.setPassword(password);
return mysql_obj;
}
public static String getTweets(BigInteger id){
Connection connection = startDBConnection(server_name,twitter_databse,username,password);
ResultSet resultSet = null;
String tweet = new String();
try {
Statement statement = connection.createStatement();
String query = SQL_queries.get_tweets_on_id + id.toString();
//Execute the query
resultSet = statement.executeQuery(query);
while(resultSet.next()){
tweet = resultSet.getString("content");
}
resultSet.close();
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
finally{
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return tweet;
}
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助。