2009-12-27 3 views
6

Мы застреваем в ситуации, когда один из наших процессов занимает 3 часа вычислений, не касаясь базы данных. Соединение, которое было выполнено до вызова процесса, закрывается сервером Oracle, и любой последующий запрос или фиксация вызывает закрытое исключение соединения.IDLE параметр времени ожидания в Oracle

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

Мы попытались изменить EXPIRE_TIMEOUT в sqlnet.ora, но это тоже не помогло.

Что мы можем сделать для решения этой проблемы?

+1

Если вы не используете подключение для такого долгого времени, почему бы не закрыть его и позже получить новое соединение, когда вам это нужно? Удержание ресурсов, которые вам не нужны в течение столь длительного времени, является расточительным. –

+0

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

ответ

7

Что такое ошибка, которую вы получаете, когда вы пытаетесь использовать соединение?

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

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

Фактическое сообщение об ошибке Oracle, которое вы получаете, укажет, какая из этих альтернатив вызывает вашу проблему.

0

Независимо от того, какую базу данных вы используете, это плохая идея предположить, что ваше соединение будет жить, когда вы хотите его использовать. Один из способов справиться с этим - создать функцию для возврата активного соединения к соответствующей базе данных и вызвать ее каждый раз, когда вам понадобится дескриптор/объект/все для данной базы данных. Программа поддерживает список баз данных и связанный с ними объект соединения. Если объект соединения является живым, когда функция вызвана, все хорошо и хорошо, и объект возвращается после того, как функция что-то делает с ним, чтобы убедить базу данных держать ручку/объект/открытую. Если нет активного объекта связи, процедура открывает новый и возвращает это. Полезно иметь вторую рутину, которая проходит по таймеру, который истекает через 1 минуту или около того. Когда таймер истекает и вызывается вторая подпрограмма, он просматривает список подключений к базе данных, ища те, у которых нет активности в течение установленного времени (что значительно меньше значения времени ожидания сеанса базы данных). Те, которые слишком долго неактивны, закрываются и очищаются.

+0

Спасибо за ответ, так как вы можете видеть мои комментарии по этому вопросу, его сторонний код, который мы используем, и рекомендуемое ими решение состоит в том, что мы уменьшаем параметр idletimeout. –

3

Ирфан,

  1. Пожалуйста, убедитесь, что у вас есть RESOURCE_LIMIT = TRUE в файле init.ora для того, чтобы изменения вступили в силу.

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

select profile from dba_users where username = 'TEST_USER'; 
    PROFILE1 

выбрать профиль, resource_name, ограничить от dba_profiles, где профиль = 'profile1' и
resource_name = 'IDLE_TIME'

3 Если пользователь asigned к настраиваемый профиль, убедитесь, что параметры для настраиваемого профиля установлены соответствующим образом. Вы также должны посмотреть на параметр connect_time (по умолчанию или настраиваемый профиль в зависимости от того, что вам подходит. По истечении времени соединения соединение прекращается.)

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

Полезные ссылки.

http://www.adp-gmbh.ch/blog/2005/april/17.html 
http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:453256655431 

Спасибо,

Раджеш

+0

init.ora не имеет переменной resource_limit, я полагаю, что его значение по умолчанию установлено false. Значит ли это, что IDLE_TIME установлен в меньшие значения, где resource_limit - false. ИЛИ установлено значение UNLIMITED. Beacuase, если он по умолчанию не ограничен, мне не нужно ничего делать. мысли –

+0

из документации, кажется, что для параметра resource_limit установлено значение flase (которое по умолчанию), оно отключает принудительные действия ограничений ресурсов. Я не уверен, что это дает неограниченное время для IDLE_TIME. Что вы получаете, когда выполняете выберите профиль из dba_users где username = ; ? –

+0

Укажите DEFAULT, если вы хотите опустить лимит для этого ресурса в этом профиле. Пользователь, которому присвоен этот профиль, зависит от этого ресурса, указанного в профиле DEFAULT. Первоначально профиль DEFAULT определяет неограниченные ресурсы. Вы можете изменить эти ограничения с помощью инструкции ALTER PROFILE http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_6010.htm#i2065930 –

0

кажется фактическая причина connection closed exception такой же, как то, что @Justin Cave отметил в своем ответе:

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

Фактическое сообщение об ошибке Oracle, которое вы получаете, укажет, какие из этих альтернатив вызывают .

Если еще кто-то хочет знать IDLE_TIME и CONNECT_TIME настроен для профиля, то можно выполнить ниже запрос:

select * from user_resource_limits user_resource where user_resource.resource_name in ('IDLE_TIME','CONNECT_TIME');