Таким образом, я отслеживаю ошибку в течение дня или двух, которая происходит на удаленном сервере, на котором у меня мало контроля. Внутри и вне моего кода я предоставляю jar файл нашей команде пользовательского интерфейса, которая обертывает postgres и предоставляет хранилище для данных, которые пользователи импортируют. Процесс импорта очень медленный из-за нескольких причин, один из которых заключается в том, что пользователи импортируют непредсказуемые большие объемы данных (которые мы не можем реально сократить). Это привело к целому множеству вопросов времени.
После некоторого предварительного расследования я сузил его до jdbc в базу данных postgres - это время. У меня было много проблем с репликацией этого на моей локальной тестовой установке, но, наконец, удалось, уменьшив "socketTimeout" свойств соединения до 10 секунд (там больше 10 секунд между каждым вызовом, сделанным в соединении).
Теперь мой вопрос: какой лучший способ сохранить это в живых? Я установил 'tcpKeepAlive' в true, но это, похоже, не имеет эффекта, мне нужно опросить соединение вручную или что-то в этом роде? Из того, что я читал, я предполагаю, что опрос является автоматическим и контролируется ОС. Если это правда, я действительно не контролирую настройки ОС в среде выполнения, что было бы лучшим способом справиться с этим?
Я рассматривал возможность тестирования соединения каждый раз, когда он используется, и если он истечет, я просто создаю новый. Будет ли это правильным курсом действий или есть лучший способ сохранить связь живым? Я только что посмотрел этот пост, где люди предлагают, чтобы вы открывали и закрывали соединение для каждого запроса: когда мое приложение теряет соединение, как его восстановить?
В моей ситуации у меня есть серия последовательных вставок, которые происходят в одном потоке, если один из них терпит неудачу, все они терпят неудачу. Для этого я использовал транзакции:
m_Connection.setAutoCommit(false);
m_TransactionSave = m_Connection.setSavepoint();
// Do something
m_Connection.commit();
m_TransactionSave = null;
m_Connection.setAutoCommit(true);
Если я продолжаю повторное подключение или использую пул соединений, например PGBouncer (как кто-то, предлагаемый в комментариях), как я могу продолжать эту транзакцию через них?
Подключение JDBC к PostGres может быть настроено с настройкой keep-alive. Здесь была затронута проблема: JDBC продолжает оставаться в живых. Кроме того, есть страница справки параметров.
Из примечаний к этому вы можете добавить следующие параметры соединения для подключения JDBC:
tcpKeepAlive=true;
Сокращение socketTimeout должно ухудшить ситуацию, а не лучше. Значение socketTimeout является мерой того, как долго соединение должно ждать, когда он ожидает, что данные поступят, но это не так. Сделать это дольше, а не короче было бы моим инстинктом.
Возможно ли, что вы используете PGBouncer? Этот процесс будет активно убивать соединения со стороны сервера, если нет активности.
Наконец, если вы работаете в Linux, вы можете изменить настройки TCP keep alive с помощью следующих настроек: сохранить настройки. Я уверен, что что-то подобное существует для Windows.