Как восстановить соединение JDBC после тайм-аута?
У меня есть длительный метод, который выполняет большое количество собственных запросов SQL через EntityManager (TopLink Essentials). Каждый запрос выполняется всего за миллисекунды, но их много тысяч. Это происходит в рамках одной транзакции EJB. Через 15 минут база данных закрывает соединение, что приводит к следующей ошибке:
Exception [TOPLINK-4002] (Oracle TopLink Essentials - 2.1 (Build b02-p04 (04/12/2010))): oracle.toplink.essentials.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Closed Connection
Error Code: 17008
Call: select ...
Query: DataReadQuery()
at oracle.toplink.essentials.exceptions.DatabaseException.sqlException(DatabaseException.java:319)
.
.
.
RAR5031:System Exception.
javax.resource.ResourceException: This Managed Connection is not valid as the phyiscal connection is not usable
at com.sun.gjc.spi.ManagedConnection.checkIfValid(ManagedConnection.java:612)
В пуле соединений JDBC я установил is-connection-validation-required="true"
а также connection-validation-method="table"
но это не помогло.
Я предположил, что валидация JDBC-соединения предназначена именно для устранения именно такого рода ошибок. Я также посмотрел на расширения TopLink (http://www.oracle.com/technetwork/middleware/ias/toplink-jpa-extensions-094393.html) для каких-то настроек тайм-аута, но ничего не нашел. Существует также файл конфигурации сеанса TopLink (http://download.oracle.com/docs/cd/B14099_19/web.1012/b15901/sessions003.htm), но я не думаю, что там есть что-то полезное.
У меня нет доступа к таблицам Oracle DBA, но я думаю, что Oracle закрывает соединения через 15 минут в соответствии с настройкой в переменной профиля CONNECT_TIME.
Есть ли другой способ заставить TopLink или пул JDBC восстановить закрытое соединение?
База данных - Oracle 10g, сервер приложений - Sun Glassfish 2.1.1.
3 ответа
Если у вас нет какого-либо аварийного переключения RAC, когда соединение будет разорвано, оно завершит сеанс и транзакцию.
Администраторы, возможно, установили некоторые ограничения, чтобы предотвратить незапланированные транзакции или отдельное задание, "включающее" соединение в пуле. Обычно вы не хотите блокировать соединение в пуле на длительный период.
Если эти запросы не обязательно являются частью одной и той же транзакции, вы можете попытаться завершить и перезапустить новое соединение.
Можете ли вы реструктурировать свой код так, чтобы он завершился менее чем за 15 минут. Хранимая процедура в фоновом режиме может выполнять работу намного быстрее, чем перетаскивать результаты тысяч операций по сети.
Все реализации JPA (работающие в контейнере Java EE) используют источник данных со связанным пулом соединений для управления связью с базой данных.
Сам контекст постоянства связан с источником данных через соответствующую запись в persistence.xml
, Если вы хотите изменить параметры тайм-аута соединения на стороне клиента, соответствующий пул соединений должен быть переконфигурирован.
В Glassfish параметры тайм-аута, связанные с пулом соединений, можно изменить, изменив настройки пула, как указано в следующих ссылках:
- Изменение настроек времени ожидания в GlassFish 3.1
- Изменение настроек времени ожидания в GlassFish 2.1
На стороне сервера (чьи настройки ниже, чем настройки клиента, было бы более важным), базу данных Oracle можно настроить так, чтобы профили базы данных были связаны с учетными записями пользователей. Параметры сеанса idle_time и connect_time профиля будут представлять собой важные параметры тайм-аута в этом аспекте взаимодействия клиент-сервер. Если профиль не был установлен, то по умолчанию время ожидания не ограничено.
Я вижу, ты установил свой connection-validation-method="table"
а также is-connection-validation-required="true"
, но вы не упоминаете, что указали таблицу, по которой вы проверяли; ты поставил validation-table-name="any_table_you_know_exists"
и предоставить какое-либо существующее имя таблицы? validation-table-name="existing_table_name"
необходимо.
Смотрите эту статью для более подробной информации о проверке соединения.
Связанная статья Stackru с похожей проблемой - он хочет очистить весь пул недействительных соединений.