После перезагрузки сервера соединение оракула с сервера Tomcat испытывает таймаут каждую ночь. До перезагрузки соединение не сделало тайм-аута. Теперь, утром, приложение бросает ошибку соединения JDBC при доступе к DB. Перезапуск Tomcat исправляет проблему. Я предполагаю, что это происходит из-за восстанавливаемых соединений. Я думаю, это происходит из-за DB Oracle, приводящего к таймауту сессии. Как тайм-аут сессии может быть отключен в Oracle 11 г?
Спасибо!
Steve
Config.groovy с dev и тестом опущен.
dataSource {
pooled = true
}
hibernate {
cache.use_second_level_cache = true
cache.use_query_cache = true
cache.provider_class = 'net.sf.ehcache.hibernate.EhCacheProvider'
}
// environment specific settings
environments {
production {
dataSource {
driverClassName = "oracle.jdbc.driver.OracleDriver"
username = "XXXXX"
password = "XXXXXX"
dialect = "org.hibernate.dialect.Oracle10gDialect"
dbCreate = "update" // one of 'create', 'create-drop','update'
url = "jdbc:oracle:thin:@XXXXXX:1521:xxxx"
}
} }
Обычно это контролируется профилем, связанным с пользователем, от имени которого подключается Tomcat.
SQL> SELECT PROFILE, LIMIT FROM DBA_PROFILES WHERE RESOURCE_NAME = 'IDLE_TIME';
PROFILE LIMIT
------------------------------ ----------------------------------------
DEFAULT UNLIMITED
SQL> SELECT PROFILE FROM DBA_USERS WHERE USERNAME = USER;
PROFILE
------------------------------
DEFAULT
Так, пользователь, к которому я подключен, имеет неограниченное время простоя - без тайм-аута.
Знает ли база данных, что соединение разорвано, или сеанс все еще указан в v $ session? Я думаю, это будет означать, что он отбрасывается сетью. Вы знаете, как долго он может оставаться в режиме ожидания, прежде чем столкнется с проблемой, и имеет ли это какое-либо сходство со значениями простоя TCP (net.ipv4.tcp_keepalive_time, tcp_keepalive_probes и tcp_keepalive_interval из sysctl, если я правильно помню)? Не могу вспомнить, сохраняются ли изменения sysctl по умолчанию, но это может быть что-то, что было изменено, а затем сброшено при перезагрузке.
Также вы можете сбросить свои JDBC-соединения, не возвращая весь сервер; конечно, можно в WebLogic, что, как я понимаю, мало помогает, но я не знаком с эквивалентами Tomcat.
Проверяйте настройки пула подключений приложений, а не изменяйте какие-либо настройки тайм-аута сеанса в базе данных Oracle. Это нормально, что они истекают по таймауту.
Посмотрите здесь: http://grails.org/doc/1.0.x/guide/3.%20Configuration.html#3.3%20The%20DataSource
Вы уверены, что правильно установили параметр «объединенный»?
Привет, Ларс
РЕДАКТИРОВАТЬ:
На первый взгляд, ваша конфигурация выглядит нормально.
Я столкнулся с этой проблемой сегодня. Возможно, это связано с вашей болью:
«Бесконечный цикл исключений, если приложение запускается, когда база данных отключена для обслуживания»
Скорее всего, это вызвано пулом соединений вашего приложения, а не проблемой СУБД Oracle. Большинство пулов соединений имеют оператор проверки, который может выполняться перед тем, как выдать вам соединение. В oracle вы бы хотели "Select 1 from dual".
Причина, по которой это стало происходить после перезапуска сервера, заключается в том, что пул соединений, вероятно, был добавлен без перезапуска, и вы только сейчас впервые столкнулись с использованием пула соединений. Какова дата модификации ваших файлов ресурсов, которые имеют дело с соединениями с базой данных?
Пример Validate Query:
<Resource name="jdbc/EmployeeDB" auth="Container"
validationQuery="Select 1 from dual" type="javax.sql.DataSource" username="dbusername" password="dbpassword"
driverClassName="org.hsql.jdbcDriver" url="jdbc:HypersonicSQL:database"
maxActive="8" maxIdle="4"/>
EDIT:. В случае с Grails существуют аналогичные опции конфигурации для пула grails. Пример для Grails 1.2 (см. примечания к выпуску Grails 1.2)
dataSource {
pooled = true
dbCreate = "update"
url = "jdbc:mysql://localhost/yourDB"
driverClassName = "com.mysql.jdbc.Driver"
username = "yourUser"
password = "yourPassword"
properties {
maxActive = 50
maxIdle = 25
minIdle = 5
initialSize = 5
minEvictableIdleTimeMillis = 60000
timeBetweenEvictionRunsMillis = 60000
maxWait = 10000
}
}
Адам уже предложил профили баз данных.
Вы можете проверить файл SQLNET.ORA. Там есть параметр EXPIRE_TIME, но он предназначен для обнаружения потерянных соединений, а не для разрыва существующих.
Учитывая, что это происходит в течение ночи, это больше похоже на таймаут простоя, который может быть связан с брандмауэром между сервером приложений и сервером базы данных. Установка параметра EXPIRE_TIME может остановить это (так как каждые 10 минут будет выполняться проверка, чтобы убедиться, что клиент жив).
Или, возможно, база данных выключается и перезапускается, и это убивает соединения.
В качестве альтернативы вы можете настроить tomcat с validationQuery, чтобы он автоматически перезапускал соединение без перезапуска tomcat