Java jdbc mysql connector: как разрешить отключение после длительного простоя

Я использую red5 1.0.0rc1 для создания онлайн-игры. Я подключаюсь к базе данных MySQL, используя соединитель jdbc mysql v5.1.12

Кажется, что через несколько часов бездействия мое приложение может продолжить выполнение запросов, потому что соединение с db закрылось, и я должен перезапустить приложение.

как я могу решить проблему?

Kfir

Ответ 1

Драйвер MySQL JDBC имеет функцию автоматического повторного подключения, которая может быть полезна в некоторых случаях; см. " Имена классов драйверов/источников данных, синтаксис URL и свойства конфигурации для Connector/J " 1 и ознакомьтесь с предостережениями.

Второй вариант - использовать пул соединений JDBC.

Третий вариант - выполнить запрос, чтобы проверить, что ваше соединение все еще живо в начале каждой транзакции. Если соединение не работает, закройте его и откройте новое соединение. Общий запрос - это SELECT 1. Смотрите также:


Простое решение состоит в том, чтобы изменить свойства конфигурации MySQL, чтобы установить время простоя сеанса на действительно большое число. Тем не мение:

  • Это не поможет, если ваше приложение может простаивать в течение очень долгого времени.
  • Если ваше приложение (или какое-либо другое приложение) пропускает соединения, увеличение времени простоя может означать, что потерянные соединения остаются открытыми бесконечно... что плохо для использования памяти базы данных.

1 - Если ссылка не работает (снова), пожалуйста, Google для цитируемого заголовка страницы, затем отредактируйте ответ, чтобы обновить его с новым URL.

Ответ 2

Ну, вы снова открываете соединение.

Пулы соединений (которые очень рекомендуются, BTW, и если вы запускаете Java EE, ваш контейнер - Tomcat, JBoss и т.д. - может предоставить javax.sql.DataSource через JNDI, который может обрабатывать пул и больше для вас) проверять соединения перед их передачей, выполнив очень простой запрос проверки (например, SELECT 1 или что-то еще). Если запрос проверки не работает, он отбрасывает соединение и открывает новый.

Увеличение времени ожидания подключения или сервера имеет тенденцию просто откладывать неизбежное.

Ответ 3

У меня была одна и та же проблема для моего приложения, и я удалил тег idle time out Thats it

Это действительно сработало попробуйте это, я использовал сервер Jboss, тем, что внесли следующее изменение в файл mysql-ds.xml.

Сообщите мне, если у вас есть больше сомнений

Ответ 4

Нормальная идиома JDBC заключается в том, чтобы получить и закрыть Connection (а также Statement и ResultSet) в кратчайшей возможной области, то есть в том же блоке try-finally метод при выполнении запроса. Вы не должны держать соединение открытым все время. БД будет тайм-аут и вернуть его рано или поздно. В MySQL это по умолчанию через 8 часов.

Чтобы улучшить производительность соединения, вы должны действительно рассмотреть возможность использования пула соединений, например c3p0 (здесь руководство разработчика). Обратите внимание, что даже при использовании пула соединений вам все равно нужно написать правильный код JDBC: получить и закрыть все ресурсы в кратчайшей возможной области. Пул соединений в свою очередь будет беспокоиться о фактическом закрытии соединения или просто отпустить его обратно в пул для дальнейшего повторного использования.

Вот пример запуска, как ваш метод, получающий список сущностей из БД, должен выглядеть так:

public List<Entity> list() throws SQLException {
    // Declare resources.
    Connection connection = null;
    Statement statement = null;
    ResultSet resultSet = null;
    List<Entity> entities = new ArrayList<Entity>();

    try {
        // Acquire resources.
        connection = database.getConnection();
        statement = connection.createStatement("SELECT id, name, value FROM entity");
        resultSet = statement.executeQuery();

        // Gather data.
        while (resultSet.next()) {
            Entity entity = new Entity(); 
            entity.setId(resultSet.getLong("id"));
            entity.setName(resultSet.getString("name"));
            entity.setValue(resultSet.getInteger("value"));
            entities.add(entity);
        }
    } finally {
        // Close resources in reversed order.
        if (resultSet != null) try { resultSet.close(); } catch (SQLException logOrIgnore) {}
        if (statement != null) try { statement.close(); } catch (SQLException logOrIgnore) {}
        if (connection != null) try { connection.close(); } catch (SQLException logOrIgnore) {}
    }

    // Return data.
    return entities;
}

См. также:

Ответ 5

У вас есть определенный validationQuery (например, выбрать 1)? Если нет, использование запроса проверки поможет.

Ответ 6

Вы можете проверить здесь для аналогичной проблемы.

Добавить '? autoReconnect = true' в конец вашей базы данных. JDBC-URL (без кавычек) работал у меня.

Ответ 7

Я видел, что ? autoReconnect = true не работал у меня.

Что я сделал, просто создает функцию, называемую: executeQuery с:

private ResultSet executeQuery(String sql, boolean retry) {
    ResultSet resultSet = null;
    try {
        resultSet = getConnection().createStatement().executeQuery(sql);
    } catch (Exception e) {
            // disconnection or timeout error
        if (retry && e instanceof CommunicationsException || e instanceof MySQLNonTransientConnectionException
                        || (e instanceof SQLException && e.toString().contains("Could not retrieve transation read-only status server"))) {
            // connect again        
            connect();
            // recursive, retry=false to avoid infinite loop
            return executeQuery(sql,false);
        }else{
            throw e;
        }
    }
    return resultSet;
}

Я знаю, я использую строку для получения ошибки.. нужно сделать это лучше.. но это хорошее начало, а WORKS: -)

Это почти все причины из-за отключения.