Java和MySQL:超过'max_user_connections'异常

时间:2014-06-20 11:44:46

标签: java mysql jdbc

对于大学来说,用Java开发多人游戏是我的运动。客户端之间的通信不应使用套接字等处理,而是在MySQL数据库的帮助下,客户端在游戏中添加其步骤。因为它是一个骰子游戏,所以不需要很多查询。 (每个游戏会话大约需要30个查询)。

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

  

com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:用户my_username已超过'max_user_connections'活动连接

我的查询在DatabaseHelper.java类中执行。结果将在项目的另一个类中返回和评估。由于我使用MVC模式,因此我会在控制器或模型类中评估结果。

这是我在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();
   }

所以我试过了:

  • 在每次查询后关闭语句和ResultSet
  • 使用db_close()关闭finally块中数据库的连接
  • 永远不会返回ResultSet(发现这可能会导致性能泄漏)

stackTrace在DatabaseHelper.java类中引导到行

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

但我找不到我的错误,为什么我仍然得到这个例外。

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

1 个答案:

答案 0 :(得分:0)

问题是您超出了与该数据库的允许连接集。很可能这个限制与#34; 1&#34;完全相同或非常接近。因此,一旦您请求第二次连接,您的程序就会崩溃。

您可以使用commons-dbcp之类的连接池系统来解决此问题。 这是推荐的方法,下面的其他解决方案只有在您不使用外部资源时才能使用。

如果您在解决方案中使用的外部代码中禁止使用,则可以执行以下操作:

创建一个&#34;数据库&#34;类。这个类只有这个类连接到数据库,每个程序运行只执行一次。你设置它,它连接到数据库,然后创建所有的查询并在这个类中运行,在Java中我们称这个构造为&#34; singleton&#34;。它通常有一个private构造函数和一个public static方法,它返回自身的唯一实例。您可以在程序的整个实时时间内保持此连接,并且只有在它停止时才会重新激活它。基本上你实现了一个&#34;连接池&#34;对于池大小的具体情况&#34; 1&#34;。

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

当程序终止时,关闭Connection(使用关闭挂钩)。