ODP.NET: предотвращение тайм-аутов подключения с помощью пула подключений

На одном сайте я могу подключиться к базе данных Oracle с помощью SQL Developer, оставить ее в бездействии на долгое время (например,> 60 минут) и вернуться, и все в порядке. На втором сайте, если он простаивает более 5-10 минут (я точно не подсчитал), он оставляет SQL Developer в состоянии, когда новые операции истекают по таймауту, и мне нужно вручную «Отключиться», а затем повторно подключиться по порядку. делать что-нибудь полезное. Похоже, это тайм-аут соединения на втором сайте, и я не знаю, что его вызывает (и я хотел бы знать, как его отключить, хотя это не мой главный вопрос).

Моя программа использует ODP.NET и обрабатывает данные, которые поступают рывками. Каждые 30 минут (для обсуждения) он будет получать кучу данных для обработки, которая будет включать в себя несколько повторных подключений. Он также использует пул соединений. Я установил для пула подключений время жизни 5 минут.

На втором сайте (а не на первом) я вижу, что моя программа будет получать исключения тайм-аута соединения (например, ORA-03113) в начале каждого всплеска данных. Я считаю, что происходит то, что во время всплеска данных пул соединений используется так, как задумано. В конце спурта проверяется "Время жизни соединения", и соединение не слишком старое, поэтому оно остается в пуле соединений. Затем, через 30 минут, когда поступают новые данные, соединение извлекается из пула (и не проверяется на время жизни или тайм-аут) и используется, и время ожидания истекает, как я вижу в SQL Developer.

Как я могу избежать тайм-аута подключения, но при этом использовать пул подключений во время всплесков? Из документации (и моего опыта) кажется, что соединение проверяется на время жизни только тогда, когда оно попадает в пул, а не когда выходит.


person Andy Jacobs    schedule 09.12.2010    source источник
comment
недостаточно разбирался в этих вопросах, но у нас была очень похожая проблема (сменили дата-центры). новый центр обработки данных уничтожит любой порт, который был открыт без активности дольше X минут (у нас была ТОЧНАЯ проблема, как и у вас в SQL Developer и других длительных процессах. Мы отказались от хостинга, и они закончили up, не убивая порты ora (но они вкратце рекомендовали нам реализовать импульс только для соединений ora, которые были отклонены из-под контроля), но это потребовало работы с их стороны. удачи!   -  person Harrison    schedule 09.12.2010


Ответы (3)


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

Сводка TL; DR состоит в том, что драйверы ODP.NET и реализация .NET плохо взаимодействуют друг с другом, и поэтому ваш обычный запуск стандартных настроек пула соединений, похоже, не работает точно так, как вы ожидаете.

  • Connection Lifetime является основным нарушителем. Я не уверен, что этот блог все еще применим, поскольку он довольно старый, но я еще не нашел никакой документации, чтобы опровергнуть его, и, похоже, он подтверждает поведение, которое я наблюдаю. Согласно блогу, Connection Lifetime убивает старую сессию, как и ожидалось, но проверка этого параметра происходит только при обращении к базе данных. Другими словами, .NET никогда не уничтожит длительные простаивающие сеансы.
  • Если в вашем профиле пользователя Oracle для IDLE_TIME установлено значение (а не UNLIMITED), то в конечном итоге эти параметры длительного простоя будут SNIPED базой данных. Это может в конечном итоге вызвать проблемы на стороне .NET, потому что, если вы явно не проверяете, что ваши соединения все еще открыты, .NET будет обслуживать эти SNIPED соединения, как если бы они все еще были доступны (таким образом, возникает указанная выше ошибка ORA тайм-аута).
  • Уловка для решения этой проблемы заключается в том, чтобы убедиться, что в строке подключения есть Data Validation=True;. Это гарантирует, что .NET будет проверять возможность подключения к сеансу, прежде чем обслуживать подключение до следующего вызова службы. Когда эта проверка видит сеанс SNIPED, она удаляет его из пула соединений .NET.

Учитывая эту информацию, наиболее вероятно, что исходная проблема OP проявлялась только на одном сайте из-за комбинации различных настроек базы данных и / или частоты обращений .NET к базе данных. У него могла быть проблема в обеих средах, но если бы пользователи в одной среде выполняли вызовы достаточно часто, чтобы Connection Lifetime выполнял свою работу, он никогда бы не увидел эти тайм-ауты в этой базе данных.

Я все еще не понял, как убить простаивающее соединение в .NET до того, как произойдет какой-либо снайпер Oracle IDLE_TIME, но пока вы используете этот параметр Data Validation = True, вы, надеюсь, сможете обойти эту проблему.

person DanK    schedule 15.12.2016

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

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

person victor6510    schedule 11.03.2013

Вы можете указать бесконечный тайм-аут, установив для свойства OracleCommand.ConnectionTimeout значение 0. В этом случае таймаута не будет (по крайней мере, на стороне клиента).

В этом случае также используется ConnectionPool.

person Tony Kh    schedule 10.12.2010
comment
Спасибо, Тони, но я считаю, что этот параметр сообщает Oracle, как долго ждать ответа. Проблема, которую я вижу, заключается в том, что соединение переходит в состояние, при котором оно никогда не получит ответа. Таким образом, этот параметр позволит избежать исключения, но моя программа все равно никогда не получит ответа, поэтому я не рассматриваю это как решение. - person Andy Jacobs; 12.12.2010