Я хочу автоматически переподключиться и повторно отправить последний SQL-запрос, если соединение закрыто (например, на сервере БД, а не потому, что я его закрою).
Я знаю, что мог бы сделать connection.isValid() (что просто SELECT 1 в большинстве реализаций драйверов) перед отправкой каждого запроса, но это расточительно. Я добавлю задержку туда-обратно к каждому из моих запросов.
Я хотел что-то вроде:
Exception.Есть ли рекомендации по этому поводу? Я не могу представить, что я первый, кто хочет что-то подобное.
Я думаю о том, чтобы сделать обертку вокруг моего драйвера java.sql.Connection и запустить этот алгоритм за кулисами, но если что-то еще есть, я был бы признателен, если бы мне не пришлось изобретать колесо (я пытался погуглить, но ничего не нашел) .
PS: мне не нужен пул соединений, потому что я буду использовать его внутри экземпляра AWS Lambda, и все известные мне пулы соединений будут просто запускаться isValid перед каждым запросом.
Преодолейте свое отвращение и используйте пул соединений, например. Апач ДБКП. Обо всем этом позаботится за вас и нет, вызывая isValid() перед каждым запросом, но обычно отправляя SELECT 1 в базу данных. Совет запускать isValid() перед каждым запросом — плохая практика: это равносильно попытке предсказать будущее. Соединение все еще может не работать после этого, и вам все равно придется иметь дело с этим. @ElliottFrisch
@user207421 user207421 Мммм, обычно isValid() использует SELECT 1 против базы данных. И это также метод, который пул соединений будет использовать для проверки соединения (но я согласен с вами, что лучше позволить пулу соединений сделать это за вас).
@ user207421 большинство реализаций драйверов JDBC вызывают SELECT 1 внутри isValid()
Я буду запускать это внутри AWS Lambda, чем меньше у меня библиотек, тем лучше для холодного запуска. Кроме того, экземпляры AWS Lambda могут иметь только 1 соединение, поэтому это будет пул соединений только для 1 соединения... так что это похоже на тяжелое решение для конкретной проблемы.
Попытка протестировать после, который вы сделали для своего запроса, по-прежнему будет стоить дороже (как во время выполнения, так и в вашей собственной реализации).
Эта проблема очень связана с AWS Lambda, потому что экземпляр Lambda переходит в спящий режим после выполнения своего вызова. Как только появится новый вызов, Lambda будет разбужена, и соединение, которое я создал и кэшировал (поскольку для создания соединения требуется некоторое время, и мы платим за время в Lambda), может быть уже отключено.
@ElliottFrisch, не могли бы вы подробнее рассказать, почему это будет стоить дороже? Насколько я вижу, в тот момент, когда я попытаюсь выполнить запрос с отключенным соединением, произойдет сбой (столько же времени, сколько isValid потребуется для сбоя). Тогда и переподключение будет такое же время, так где это будет стоить дороже?
Потому что вам придется писать и поддерживать этот код (который уже существует в isValid), а затем вам придется вручную поддерживать соединение, повторно подключаться и запрашивать (и также писать этот код).
хм, имеет смысл... жаль, что никто не сделал это в виде небольшой библиотеки раньше
@ElliottFrisch Я поднимал эту проблему в HikariCP раньше здесь: github.com/brettwooldridge/HikariCP/issues/1304, и, поскольку Lambda зависает, даже пулы соединений могут не обслуживать меня.
Если ваш контейнер зависнет, ваш собственный код тоже зависнет. Вам нужно разобраться в первопричинах ваших «зависаний».
Лямбда зависает по дизайну.
Я пока пойду с isValid, может быть, протестирую, как HIkariCP ведет себя на этом.
Проверять ваше соединение каждый раз действительно излишне (особенно учитывая, что пулы соединений сделают это за вас, прежде чем арендовать соединение). Просто выполните запрос и будьте готовы к ошибкам.
@ElliottFrisch Вы не имеют «проверить после, что вы сделали свой запрос». Это вызовет исключение или преуспеет. Нет проблем с временным окном.
@MarkRotteveel да, но поскольку я буду использовать пул соединений только для проверки соединения, я мог бы просто сделать это сам и вообще не иметь пула соединений.




Написание собственной оболочки вокруг java.sql.Connection, которая перехватывает ошибки и повторяет операторы после восстановления разорванного соединения, звучит заманчиво, но тогда вам также нужно будет написать свою собственную PreparedStatement и так далее, верно?
Возможно, было бы лучше сосредоточить все ваши вызовы JDBC в нескольких местах вашего приложения, т. е. написать собственную (тонкую) абстракцию для вызовов JDBC. Затем вы можете поместить свою магию повторных попыток в одно место.
Я бы определенно использовал пул соединений. Любой достойный пул соединений можно настроить так, чтобы нет отправлял запрос на сервер. Даже если вы не можете этого избежать, это на много дешевле, чем открытие и закрытие соединения с базой данных.
Что вы имеете в виду под be configured to not send a query to the server? Зачем мне это? Вы говорите, что есть пулы соединений, которые при сбое соединения автоматически повторяют попытку?
Я имел в виду, что вы, вероятно, можете настроить большинство пулов соединений, чтобы они не отправляли SELECT 1 на сервер автоматически. Извините за небрежность. У меня сложилось впечатление, что вы обеспокоены этим. Я не знаю, существуют ли пулы соединений, которые автоматически восстанавливают разорванные соединения, но это меня не удивит. В любом случае, я хочу призвать вас использовать пул соединений.
Я хотел использовать пул соединений, но я буду запускать свой код на AWS lambda, и это немного усложняет ситуацию. AWS Lambda замораживает контейнер, когда код возвращается, и он должен вернуться через несколько секунд, иначе произойдет тайм-аут. Так что это в основном однопоточная модель. Если я установлю пул соединений, это будет пул соединений из 1 соединения, потоки управления которого будут заморожены AWS Lambda. Когда он разморозится, время будет неправильным. Вероятно, это сработает, просто выводите ошибки синхронизации при каждом новом вызове. Поэтому я подумал, что могу упростить проверку isValid самостоятельно.
Очаровательный. Мой совет: просто запускайте
isValidперед каждым запросом. Попытка обнаружения постфактум будет хуже.