Почему Hibernate/JDBC/MySQL удаляет соединения через день или около того?

У меня есть несколько серверных процессов, которые время от времени отвечают на сообщения от клиентов и выполняют транзакции только для чтения.

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

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

Однако даже с c3po я получаю эту проблему около 24 часов или около того после запуска серверов.

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

Ответ 1

Драйвер MySQL JDBC истекает через 8 часов бездействия и отключает соединение.

Вы можете установить autoReconnect=true в свой URL JDBC, и это заставляет драйвер повторно подключаться, если вы попытаетесь выполнить запрос после его отсоединения. Но это имеет побочные эффекты; например состояние сеанса и транзакции не могут поддерживаться по новому соединению.

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

Подробнее читайте http://dev.mysql.com/doc/refman/5.0/en/connector-j-reference-configuration-properties.html.

Ответ 2

MySql в основном таймауты по умолчанию в 8 часов.

Я получил то же исключение и разрешил проблему после 3 суточных дней. Проверьте, используете ли вы я hibernate3. В этой версии требуется явно указать имя класса подключения. Также проверьте, находится ли jar в classpath. Проверьте шаги и комментарии ниже.

http://hibernatedb.blogspot.com/2009/05/automatic-reconnect-from-hibernate-to.html

Удалите autoReconnect=true

Ответ 3

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

Я думаю конкретно о соединениях DB2/z, но он одинаково применим ко всем серверам (база данных и тому подобное). Эти соединения потребляют ресурсы на сервере, которые лучше всего можно использовать в других местах.

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

Я все понимаю идею объединения пулов, но не столько для того, чтобы пытаться держать отдельные сеансы открытыми навсегда.

Мой совет будет следующим:

1/У вас есть три типа соединений в пуле соединений:

  • закрытый (так что на самом деле в ваш пул).
  • готово, что означает открытый, но не используемый клиентом.
  • активен, что означает использование клиентом.

2/У вашего пула соединений поддерживается небольшое количество готовых подключений, минимум N и максимум M. N можно настроить в зависимости от максимальной скорости, с которой ваши клиенты запрашивают соединения. Если количество готовых подключений когда-либо падает до нуля, вам нужно больше N.

3/Когда клиент хочет получить соединение, дайте им один из готовых (сделав его активным), а затем немедленно откройте новый, если в настоящее время меньше N готово (но не заставляйте клиента ждать этого полный, или вы потеряете преимущество объединения). Это гарантирует, что всегда будет установлено не менее N готовых подключений. Если ни один из них не готов, когда клиент хочет его, ему придется подождать, пока вы создадите новый.

4/Когда клиент заканчивается активным подключением, верните его в состояние готовности, если есть меньше, чем M готовых подключений. В противном случае закройте его. Это предотвратит наличие более чем готовых соединений M.

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

Это имеет то преимущество, что в вашем пуле соединений есть достаточно готовых И юных соединений, не перегружая сервер.

Ответ 4

Я сменил свой конфигурационный файл спящего режима, добавив строки thoses, и теперь он работает:

    <property name="connection.autoReconnect">true</property>
    <property name="connection.autoReconnectForPools">true</property>
    <property name="connection.is-connection-validation-required">true</property>

Я думаю, что использование пула c3p0 лучше и рекоммендованно, но это решение работает сейчас и не представляет проблемы ant.
Я позволил Tomcat On в течение 24 часов, и соединение не было потеряно.
Пожалуйста, попробуйте.