Соединение JDBC из другого потока блокирует доступ к выполнению запроса - PullRequest
0 голосов
/ 02 декабря 2018

У меня игровой сервер с 2-мя потоками, одним основным и одним вторым.База данных mysql

Основной поток ответов для вычисления игровой ситуации и подключения игроков к серверу, он делает много маленьких транзакций для mysql.

Второй поток вычисляет статистику, вызывая процедуру mysql.На его вычисление уходит 10 секунд.

Каждый поток использует свое собственное соединение.Но когда я запускаю вычисление статистики во втором потоке, соединение с основным потоком ожидает окончания вычислений.Таким образом, это означает, что даже если у меня есть 2 соединения и 2 потока, одно соединение ожидает завершения другого соединения.

Но когда я запускаю ту же процедуру из веб-интерфейса - блоки не появляются одновременно.

Что я делаю не так?


РЕШЕНО

    Statement stmt = null;
    try {
        stmt = con.createStatement();
        stmt.executeUpdate("call updateScores();");
    } catch (SQLException sqlEx) {
        sqlEx.printStackTrace();
    } finally {
        if (stmt != null) try { stmt.close(); } catch(Exception e) { }
    }

Я уменьшил метод execute, насколько это возможно, и все блокировки исчезли!Выше новый код для калькулятора статистики, ниже старый

public MySQLConnector(GameServer serv, String url, String user, String password) {

 /* */

    try {
        con = DriverManager.getConnection(url, user, password);
    } catch (SQLException e) {
        e.printStackTrace();
    }
}


@Override
public int update(SQLRequest r) {
    //System.out.println("Executing query " + r.getRequest());
    int id = -1;
    Statement stmt = null;
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    try {
        if (r.getParams() == null) {
            stmt = con.createStatement();
            stmt.executeUpdate(r.getRequest(), RETURN_GENERATED_KEYS);
            rs = stmt.getGeneratedKeys();
        } else {
            pstmt = con.prepareStatement(r.getRequest(), Statement.RETURN_GENERATED_KEYS);
            for (int i = 0; i < r.getParams().size(); i++) pstmt.setString(i + 1, r.getParams().get(i));
            pstmt.executeUpdate();
            rs = pstmt.getGeneratedKeys();
        }

        if (rs.next())
            id = rs.getInt(1);

    } catch (SQLException sqlEx) {
        sqlEx.printStackTrace();
    } finally {
        if (stmt != null) try { stmt.close(); } catch(Exception e) { /*can't do anything */ }
        if (pstmt != null) try { pstmt.close(); } catch(Exception e) { /*can't do anything */ }
        if (rs != null) try { rs.close(); } catch(Exception e) { /*can't do anything */ }
    }
    return id;
}

В ветке статистики:

class ScoreCalculator extends Thread {

SQLConnector db;

public ScoreCalculator(SQLConnector db) {
    this.db = db;
}

@Override
public void run() {
    Slog.l("Scores calculation started");
    SQLRequest request = new SQLRequest("updateScores()");
    db.update(request);
    Slog.l("Scores calculation finished");
}

}

Между «Вычисление началось» и «Вычисление закончено», например, застряли соединения новых игроков,потому что он пытается получить информацию из MySQL и не может это сделать

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...