Обработка закрытых соединений JDBC

#java #mysql #postgresql #jdbc #database-connection

#java #mysql #postgresql #jdbc #подключение к базе данных

Вопрос:

Я хочу автоматически переподключиться и повторно отправить последний SQL-запрос, если соединение закрыто (например, на сервере db, а не потому, что я его закрою).

Я знаю, что мог бы сделать connection.isValid() (что просто SELECT 1 в большинстве реализаций драйверов) перед отправкой каждого запроса, но это расточительно. Я добавлю задержку в оба конца к каждому из моих запросов.

То, что я хотел, было чем-то более похожим:

  • Отправляет запрос в базу данных
  • Если соединение не работает, повторно подключитесь и отправьте тот же запрос
  • Если не удается подключиться повторно, отключите соединение Exception .

Есть ли какие-либо рекомендации относительно этого? Я не могу представить, что я первый, кто хочет чего-то подобного.

Я подумываю о том, чтобы создать оболочку вокруг моего драйвера java.sql.Connection и запустить этот алгоритм за кулисами, но если там еще что-то есть, я был бы признателен, если бы мне не пришлось изобретать whell (я пытался это погуглить, но ничего не смог найти).

PS: Мне не нужен пул подключений, потому что я буду использовать его внутри экземпляра AWS Lambda, и все известные мне пулы подключений будут просто запускаться isValid перед каждым запросом.

Комментарии:

1. Увлекательно. Мой совет: просто выполняйте isValid перед каждым запросом. Попытка обнаружить постфактум будет хуже .

2. Преодолейте свое отвращение и используйте пул соединений, например Apache DBCP. Обо всем этом позаботится за вас, и не путем вызова isValid() перед каждым запросом, а обычно путем выдачи SELECT 1 базе данных. Совет запускать isValid() перед каждым запросом — плохая практика: это равносильно попытке предсказать будущее. Впоследствии соединение все равно может завершиться сбоем, и вам все равно придется иметь с этим дело. @ElliottFrisch

3. @user207421 Ммм, обычно isValid() использует SELECT 1 против базы данных. И это также метод, который пул соединений будет использовать для проверки соединения (но я согласен с вами, что лучше позволить пулу соединений делать это за вас).

4. @user207421 большинство реализаций драйверов JDBC вызывают SELECT 1 внутри isValid()

5. Я буду запускать это внутри AWS Lambda, чем меньше у меня библиотек, тем лучше для холодного запуска. Кроме того, экземпляры AWS Lambda могут иметь только 1 соединение, поэтому это будет пул соединений только для 1 соединения… так что это похоже на сложное решение для конкретной проблемы.

Ответ №1:

Написание вашей собственной оболочки вокруг, java.sql.Connection которая улавливает ошибки и повторяет инструкции после восстановления разорванного соединения, звучит заманчиво, но тогда вам также нужно было бы написать свой собственный PreparedStatement , и так далее, верно?

Возможно, было бы лучшей идеей централизовать все ваши вызовы JDBC в нескольких местах вашего приложения, т. Е. написать свою собственную (тонкую) абстракцию для вызовов JDBC. Затем вы можете применить свою магию повторных попыток в одном месте.

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

Комментарии:

1. Что вы имеете в виду под be configured to not send a query to the server ? Зачем мне это нужно? Вы хотите сказать, что существуют пулы соединений, которые при сбое соединения автоматически повторяют попытку?

2. Я имел в виду, что вы, вероятно, можете настроить большинство пулов соединений на автоматическую отправку no SELECT 1 на сервер. Извините за неаккуратность. У меня сложилось впечатление, что вы были обеспокоены этим. Я не знаю, существуют ли пулы соединений, которые автоматически восстанавливают разорванные соединения, но меня бы это не удивило. В любом случае, я хочу призвать вас использовать пул соединений.

3. Я хотел использовать пул подключений, но я буду запускать свой код на AWS lambda, и это немного усложняет дело. AWS Lambda замораживает контейнер при возврате кода, и он должен вернуться через несколько секунд, иначе наступает тайм-аут. Таким образом, это в основном однопоточная модель. Если я установлю пул подключений, это будет пул подключений из 1 соединения, потоки управления которого будут заблокированы AWS Lambda. Когда он размораживается, тайминги будут неправильными. Вероятно, это сработает, просто выводите ошибки синхронизации при каждом новом вызове. Итак, я подумал, что мог бы упростить проверку isValid самостоятельно.