У меня игровой сервер с 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 и не может это сделать