Java 和 MySQL : More than 'max_user_connections' exception

标签 java mysql jdbc

在大学里,我的练习是用 Java 开发多人游戏。客户端之间的通信不应使用套接字等进行处理,而是借助客户端在游戏中添加步骤的 MySQL 数据库。因为是骰子游戏,所以不需要很多查询。 (每个游戏 session 大约需要 30 个查询)。

我以前从未将 MySQL 与 Java 结合使用,所以这可能是初学者的错。但实际上,我在执行 java 项目时经常遇到异常。

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: User my_username already has more than 'max_user_connections' active connections

我的查询是在 DatabaseHelper.java 类中执行的。结果返回并在项目的另一个类中进行评估。因为我使用 MVC 模式,所以我在 Controller 或模型类中评估结果。

例如,这是我在 DatabaseHelper.java 类中的一个问题。其他查询类似:

private static Connection conn;

private Connection getConn() {

    return conn;
}

public void db_connect() throws ClassNotFoundException, SQLException{

    // JDBC Klassen laden
    Class.forName(dbClassName);

    // Verbindungsversuch auf 5 Sekunden setzen
    DriverManager.setLoginTimeout(5); 
    this.setConn(DriverManager.getConnection(CONNECTION,p)); // p contains the username and the database
}

public void db_close(){

    try {
        this.getConn().close();
    } catch (SQLException e) {
        if(GLOBALVARS.DEBUG)
            e.printStackTrace();
    }
}

public String[] query_myHighscores(int gameid, PlayerModel p) throws SQLException{

    List<String> rowValues = new ArrayList<String>();

    PreparedStatement stmnt;
    if(gameid == GLOBALVARS.DRAGRACE)
        stmnt = this.getConn().prepareStatement("SELECT score FROM highscore WHERE gid = ? and pname = ? ORDER BY score ASC LIMIT 0,3");
    else
        stmnt = this.getConn().prepareStatement("SELECT score FROM highscore WHERE gid = ? and pname = ? ORDER BY score DESC LIMIT 0,3");

    stmnt.setInt(1, gameid);
    stmnt.setString(2, p.getUname());

    ResultSet rs = stmnt.executeQuery();

    rs.beforeFirst();
    while(rs.next()){
        rowValues.add(rs.getString(1));
    }

    stmnt.close();
    rs.close();

    return (String[])rowValues.toArray(new String[rowValues.size()]);
}

CONNECTION 字符串是一个类似于 jdbc:mysql://my_server/my_database 的字符串

在 HighscoreGUI.java 类中,我请求这样的数据:

private void actualizeHighscores(){

    DatabaseHelper db = new DatabaseHelper();

    try{
       db.db_connect();
       String[] myScoreDragrace = db.query_myHighscores(GLOBALVARS.GAME1); // id of the game as parameter
       // using the string
   } finally {
        db.db_close();
   }

所以我尝试了:

  • 在每次查询后关闭语句和结果集
  • 在 finally block 中使用 db_close() 关闭与数据库的连接
  • 从不返回 ResultSet(发现这可能成为性能泄漏)

Stacktrace 在 DatabaseHelper.java 类中指向行

  this.setConn(DriverManager.getConnection(CONNECTION,p));

但是我找不到为什么我仍然得到这个异常的错误。

我无法更改数据库的所有设置,因为这是一个共享主机。所以我更喜欢 Java 方面的解决方案。

最佳答案

问题是您超出了允许的与该数据库的连接集。这个限制很可能正好或非常接近“1”。因此,一旦您请求第二个连接,您的程序就会崩溃。

你可以通过使用像commons-dbcp 这样的连接池系统来解决这个问题。 . 这是推荐的方法,下面的其他解决方案仅适用于您可能不使用外部资源的情况。

如果您在可能用于您的解决方案的外部代码中被禁止,您可以这样做:

创建一个“数据库”类。此类且只有此类曾经连接到数据库,并且每次程序运行仅连接一次。你设置它,它连接到数据库,然后创建所有查询并通过这个类运行,在 Java 中我们称这个构造为“单例”。它通常有一个 private 构造函数和一个返回唯一实例的 public static 方法。您可以在程序的整个运行期间保持此连接,只有在它停止时才重新激活它。基本上,您针对池大小为“1”的特定情况实现“连接池”。

public class Database {
   private static final Database INSTANCE = new Database();
   private Database() {}
   public static Database getInstance() {
      return INSTANCE;
   }
   // add your methods here.
}

当程序终止时,关闭连接(使用关闭钩子(Hook))。

关于Java 和 MySQL : More than 'max_user_connections' exception,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24326502/

相关文章:

java - 使用 java 中的单个方法/函数从任意索引处的单链表中删除节点

java - gwt setEnabled 未在 GoogleChrome 上执行

mysql - 从没有自动递增的表中获取最后一个主键

java - 删除 ArrayList 中所有出现的第一个元素

java - 如何在Java运行时添加JTextField?

php - MySQL:保持服务器时区或用户时区?

mysql - 如何删除表中的记录以便每分钟有一个读数?

java - 找不到适用于 jdbc : oracle: thin:@localhost:1521:orcl 的合适驱动程序

java - 类型不匹配 : cannot convert from element type Object to String JDBC MetaData

java - JDBC SQL 中的结果集