Mysql на Java. Как реализовать эффективные асинхронные запросы?

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

Слушатели вызываются в фоновом потоке Kryonet, и я не могу их заблокировать, потому что это повлияет на все пользователи.

Я создал свою базу данных, настроил ConnectionPool в синхронизированном классе Singleton:

private static final BasicDataSource dataSource = new BasicDataSource();

static {
    dataSource.setDriverClassName("com.mysql.jdbc.Driver");
    dataSource.setUrl("jdbc:mysql://111.111.111.111/db");
    dataSource.setUsername("server");
    dataSource.setPassword("serverpass");
}

public Connection getConnection() throws SQLException {
    return dataSource.getConnection();
}

и теперь мне нужно выполнить несколько запросов. А вот и моя проблема. Как мы знаем, запрос может занять много времени, чтобы вернуть результат, поэтому совершенно неприемлемо выполнять его в потоке «Kryonet» (когда пакет получен). Например, когда пользователь отправляет свой «RegistrationPacket», мне нужно сделать запрос к базе данных и вернуть ему результат в пакете. Когда я получаю пакет, мне нужно перевести его в фоновый режим и оттуда - отправить результат клиенту.

Вот мой вопрос: как обрабатывать запросы к базе данных в фоновом режиме с помощью Java?

Должен ли я использовать исполнителей? Потоки? Насколько я знаю, открывать поток для каждого соединения - плохая идея (вызывает более 200 рабочих). Равно (катастрофа). Если бы кто-то мог мне помочь, я был бы благодарен! :)


person Community    schedule 08.10.2016    source источник
comment
Если вам нужно вернуть результат клиенту, вам нужно заблокировать клиента. Если у вас нет сервера push; у вас есть пуш сервера?   -  person Boris the Spider    schedule 08.10.2016
comment
Клиент и сервер — это два отдельных приложения. Клиент отправляет сетевой пакет со своими данными, и сервер должен запросить эти данные в базу данных. Но он не может в обычном потоке, потому что это заморозит всю сеть :) После того, как запрос будет выполнен в фоновом режиме, мне нужно отправить результат.   -  person    schedule 08.10.2016


Ответы (1)


С jasync-sql вы можете сделать что-то вроде этого:

// Connect to DB
Connection connection = new MySQLConnection(
  new Configuration(
    "server",
    "111.111.111.111",
    3306,
    "serverpass",
    "db"
  )
);
CompletableFuture<?> connectFuture = connection.connect()
// Wait for connection to be ready   
// ...    
// Execute query
CompletableFuture<QueryResult> future = connection.sendPreparedStatement("select 0");
// Close the connection
connection.disconnect().get()

См. более подробную информацию о самой библиотеке. Это асинхронный драйвер MySQL, основанный на Netty.

person oshai    schedule 06.09.2018