数据源拒绝建立连接,来自服务器的消息:“连接太多”

时间:2010-07-08 12:45:16

标签: java mysql jdbc

我正在尝试使用连接池库连接到我的数据库:DBPool。这是我的源代码。

DBUtils.java

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;
    }
}

TwitterAPI.java

/**
 * @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;
    }
}

我是连接池业务的新手,并且决定这样做只是因为我没有收到“通信链路故障”。

更新1:要添加,我还尝试了Apache DBCP 并尝试了此example,但仍然收到相同的错误。

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)

我还检查了MySQL中my.ini文件中的max_connections变量。这是它的价值:

  

MySQL服务器的最大并发会话数   允许。其中一个连接将保留给用户   SUPER权限允许管理员即使登录也是如此   已达到连接限制。   max_connections=100

MySQL终端上的 show processlist 命令显示处于休眠状态的101个进程。

任何形式的帮助/评论都将受到赞赏

更新2 - 解决方案:: 所以,我想出了解决方案。我没有在与数据库的url连接中提到端口名称。

String url = "jdbc:mysql://" + server_name +  "/" + database;

可能因此导致许多泄漏的连接。完成后,我尝试了here给出的示例。它现在不会抛出任何错误。感谢BalusC,我认为这只是因为他对改变MySQL端口号的评论。要添加,更改MySQL端口号的方法是,方法是更改​​ my.ini 文件,但运行 MySQL实例配置向导开始 - &gt;程序 - &gt; MySQL Server 5.1 - &gt; MySQL服务器实例配置向导。值得注意的是,当未指定端口号并且程序运行顺利时,代码没有抛出任何错误。也许,JDBC默认连接到3306。如果有人对此有任何特别的想法,请分享。

我的完整源代码see my answer below

2 个答案:

答案 0 :(得分:4)

  

org.apache.commons.dbcp.SQLNestedException:无法创建PoolableConnectionFactory(数据源拒绝建立连接,来自服务器的消息:“连接太多”)

这表示某些内容正在泄漏连接。即某些东西不断关闭它们和/或返回连接池而继续获取(打开)连接。重新启动数据库以便它可以硬关闭所有打开的连接应该暂时解决问题。修复某些内容,以便在使用后正确关闭连接,可以永久解决问题。

虽然发布的JDBC代码没有遵循最佳习惯用法,但它看起来不像是连接泄漏的原因。可能数据库已经运行了几个小时/几天,并且您在早期测试期间获得了太多连接而没有关闭它们以便数据库用完它们。

答案 1 :(得分:3)

所以,我找到了解决方案。我没有在与数据库的url连接中提到端口名称。

String url = "jdbc:mysql://" + server_name +  "/" + database;

可能因此导致许多泄漏的连接。完成后,我尝试了这里给出的例子。它现在不会抛出任何错误。感谢BalusC,我认为这只是因为他对改变MySQL端口号的评论。要添加,更改MySQL端口号的方法是 NOT ,方法是更改​​my.ini文件,但是在Start - &gt;下运行MySQL实例配置向导。程序 - &gt; MySQL Server 5.1 - &gt; 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;
    }
}

<强> 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;
    }

希望这有帮助。