Почему 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 часов, и соединение не было потеряно.
Пожалуйста, попробуйте.