Вопрос

Я использую hibernate 3 с c3p0 для программы, которая постоянно извлекает данные из какого-то источника и записывает их в базу данных.Теперь проблема в том, что база данных может стать недоступной по каким-то причинам (в самом простом случае:я просто выключил его).

Если что-то должно быть записано в базу данных, исключений быть не должно — запрос должен ждать целую вечность, пока база данных снова не станет доступной.Если я не ошибаюсь, это одна из вещей, которые пул соединений может сделать для меня:если проблема с БД, просто повторите попытку подключения - в худшем случае на бесконечность.

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

Даже если я поймаю исключение, как я смогу снова повторно инициализировать спящий режим?(До сих пор без c3p0 я просто заново построил фабрику сеансов, но не удивлюсь, если это может привести к утечке соединений (или это нормально?)).

База данных представляет собой версию Virtuoso с открытым исходным кодом.

Моя конфигурация hibernate.xml.cfg c3p0:

<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>  
<property name="hibernate.c3p0.breakAfterAcquireFailure">false</property>
<property name="hibernate.c3p0.acquireRetryAttempts">-1</property>
<property name="hibernate.c3p0.acquireRetryDelay">30000</property>
<property name="hibernate.c3p0.automaticTestTable">my_test_table</property>

<property name="hibernate.c3p0.initialPoolSize">3</property>
<property name="hibernate.c3p0.minPoolSize">3</property>
<property name="hibernate.c3p0.maxPoolSize">10</property>

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

Это было полезно?

Решение

Что ж, похоже, BoneCP действительно реализовал это. Можно настроить запись транзакции и ее воспроизведение при сбое в сети или базе данных:

http: // jolbox.com/bonecp/downloads/site/apidocs/com/jolbox/bonecp/BoneCPConfig.html#setTransactionRecoveryEnabled(boolean)

Другие советы

  

Если я не ошибаюсь, это одна из вещей, которую пул соединений мог бы сделать для меня: если есть проблема с базой данных, просто повторите попытку подключения - в худшем случае для бесконечности.

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

Тем не менее, эти соединения могут устареть (например, если вы перезапустите базу данных). К счастью, большинство пулов подключений можно настроить для проверки правильности подключения и обновления их перед их распространением. c3p0 поддерживает эту функцию, как описано в настройке тестирования подключения , и вы на самом деле уже используется один из различных вариантов. Таким образом, ваши соединения должны быть обновлены, когда база данных вернется.

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

Спасибо за ответ. Кажется, я просто не понял последний абзац раздела http://www.mchange.com/projects/c3p0/index.html# configuring_recovery

Потому что на первый взгляд кажется, что c3p0 может это сделать (обнаружить устаревшие соединения и повторить попытку получения соединений на всю вечность, даже не выбрасывая исключение в код приложения (если, конечно, это не ошибка, связанная с оператором sql, а не с соединение), но в последнем абзаце - который написан довольно запутанно - кажется, что c3p0 не может гарантировать, что до 100%.

Поэтому я решил создать небольшую оболочку для методов, которые мне нужны, из интерфейса jdbc-соединения, которые пытаются восстановить соединение, если запрос не выполнен из-за ошибки соединения. Конечно, это немного странно, потому что я предпочел бы, чтобы мои компоненты использовали стандартный интерфейс подключения вместо моего собственного интерфейса, но, по крайней мере, теперь он работает чисто.

Вы забываете:

  • А как насчет ваших начатых транзакций?
  • А как насчет подготовленных операторов, которые уже были отправлены в БД?
  • и т. д.

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

В случае BoneCP (http://jolbox.com), пул обнаруживает, что произошел сбой, сначала перехватывая исключение, созданное драйвером JDBC, и обрабатывая его, либо помечая это соединение как ошибочное, либо воссоздавая весь пул соединений.

Редактировать:Сейчас этим занимаются.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top