По каким причинам я периодически получаю сбой канала связи JDBC MySQL в моей программе? - PullRequest
1 голос
/ 24 июня 2019

У меня есть экземпляр MySQL, развернутый на сервере Amazon EC2 вместе с файлом Java .Jar, который подключается к локальной базе данных для архивирования метаданных, полученных из API. У меня Java-файл автоматически запускается 4 раза в день через задачу Linux Crontab.

Мой код всегда будет запускаться и сначала нормально подключаться к MySQL, но затем он будет испытывать сбой канала связи JDBC через минуту после запуска (однако время, в течение которого это происходит, может варьироваться). Это следующее сообщение об ошибке, которое отображается на терминале:

com.mysql.cj.jdbc.exceptions.CommunicationsException: сбой линии связи

Последний пакет, успешно полученный от сервера, был 4 278 миллисекунд назад.

Перед отображением вышеуказанного сообщения об ошибке моя программа зависла. Замораживание моей программы очевидно, потому что она перестает выводить: «Точка метаданных была заархивирована». У меня есть вывод моей программы, что каждый раз точка метаданных из API архивируется соответственно в таблицы моей базы данных.

Я пытался найти много решений, чтобы решить эту проблему, и я совершенно не понимаю, что ее вызывает. Я добавил несколько параметров в мою строку URL: JDBC: MySQL: // локальный / MYDBNAME serverTimezone = EST5EDT & UseSSL = ложь и autoReconnect = истина & maxReconnects = 10 & failOverReadOnly = ложь и allowPublicKeyRetrieval = истина и useUnicode = верно и tcpKeepAlive = верно и interactiveClient = верно? Параметр autoReconnect иногда позволяет моей программе повторно подключаться к базе данных после сбоя канала связи и выполнять заново, но иногда это не помогает вообще.

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

Я гарантировал, что версия MySQL коннектора java driver.jar, которую использует моя программа, совпадает с версией установленной базы данных MySQL.

Я пытался увеличить встроенные переменные тайм-аута MySQL.

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

private void setUpConnectionToDatabase() { 
    try {
        connection = DriverManager.getConnection(
                url, username, password); // connects to server using url, username, password.

    } catch (Exception e) {
        System.out.println(e);
        connection=null;
    }
}

Ниже приведен один из моих методов, который запрашивает базу данных. Дайте мне знать, если увидите какие-либо ошибки. Другие методы в классе, по сути, следуют тому же формату. Обратите внимание, что сама переменная соединения не закрывается в методе.

public Coordinates getCoordsFromArchivedLocationData(String bioLocation) {
    Coordinates coords= new Coordinates();
    double lat=0;
    double longit=0;
    String queryStatement= "SELECT latitude, longitude FROM archived_location_data WHERE LocationName=?;";
    PreparedStatement query=null;
    ResultSet result=null;

    try {
        query = connection.prepareStatement(queryStatement);
        query.setString(1, bioLocation);
        result = query.executeQuery();
        if(result.next()) {
            lat= result.getDouble(1);
            longit= result.getDouble(2);
        }
        coords.setLatitude(lat);
        coords.setLongitude(longit);
    }
    catch(Exception e) {
        System.out.println(e);
        return coords;
    }
    finally {
        try {
            if(query != null) {
            query.close();
            }
            if(result != null) {
            result.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    return coords;


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