Как очистить пул подключений ODP.NET при ошибках подключения?

Я использую NHibernate и ODP.NET для подключения к базе данных Oracle 11g. Конечно, могут быть ошибки подключения (сбой сети, сбой БД, ...). Я обрабатываю все эти исключения в своем коде, поэтому проблем нет. Но, конечно, пользователь может повторить свои действия (возможно, это был просто короткий сетевой сбой), и вот моя проблема:

ODP.NET по умолчанию использует пул соединений. Обычно с этим проблем нет, но когда пользователь повторяет действие после ошибки соединения, NHibernate получает недопустимое (объединенное) соединение от ODP.NET. Пользователь должен повторить попытку несколько раз (пока пул не опустеет), чтобы он снова заработал.

Конечно, я могу отключить пул соединений в ODP.NET, но я бы хотел этого избежать. Я также читал о настройке, которая проверяет соединение с БД для каждого возвращаемого соединения из пула, но это добавляет дополнительный круговой обход для каждого соединения, которого я бы тоже хотел избежать.

Есть ли способ настроить ODP.NET для автоматической очистки пула соединений, когда какое-либо соединение вызывает исключение соединения?


person cremor    schedule 20.04.2011    source источник
comment
Очень хотелось бы знать, как разрешить эту ситуацию. Похоже, что нет хорошего способа справиться с этим, поскольку пул соединений заканчивается плохими соединениями в нем, и попытка развернуть фактическое соединение Oracle, которое nhibernate использует для вызова ClearAllPools, тоже не работает. Другая проблема заключается в том, что воспроизвести эту ситуацию для целей отладки - огромная боль.   -  person Harv    schedule 19.03.2013


Ответы (2)


Если вы можете использовать odac (odp) 11g, значит, для вашего пула настроена проверка соединения. Он может проверить соединение перед его использованием.

Атрибут Проверить соединение проверяет соединения, исходящие из пула. Этот атрибут следует использовать только в случае крайней необходимости, потому что он вызывает двусторонний обход базы данных для проверки каждого соединения непосредственно перед тем, как оно будет предоставлено приложению. Если недопустимые соединения встречаются редко, разработчики могут создать собственный обработчик событий для извлечения и проверки нового соединения вместо использования атрибута Validate Connection. Обычно это обеспечивает лучшую производительность.

Если этого будет недостаточно - вы можете попробовать это документ от Oracle.

Управление пулом подключений

Управление пулом соединений ODP.NET обеспечивает явное управление пулом соединений для приложений ODP.NET. Приложения могут явно очищать соединения в пуле соединений.

Используя управление пулом соединений, приложения могут делать следующее:

Примечание. Эти API-интерфейсы не поддерживаются хранимой процедурой .NET. Удалите соединения из пулов соединений с помощью метода ClearPool.

Удалите соединения во всех пулах соединений в домене приложения с помощью метода ClearAllPools.

Когда соединения удаляются из пула, ODP.NET повторно заполняет пул новыми соединениями, у которых есть по крайней мере количество соединений, установленное минимальным размером пула в строке соединения. Новые соединения не обязательно означают, что у пула будут действующие соединения. Например, если сервер базы данных не работает при вызове ClearPool или ClearAllPools, ODP.NET создает новые подключения, но эти подключения по-прежнему недействительны, потому что они не могут подключиться к базе данных, даже если база данных появится позже.

Не рекомендуется вызывать ClearPool и ClearAllPools до тех пор, пока приложение не сможет создать действительные соединения с базой данных. Разработчики .NET могут разрабатывать код, который постоянно проверяет, можно ли создать действительное соединение с базой данных, и вызывает ClearPool или ClearAllPools, когда это истинно.

Кроме того, может быть этот пост поможет вам.

Обновление: как указано @MPelletier, для oracle 12 ссылка другая.

person evgenyl    schedule 25.03.2013
comment
Как указано в моем вопросе, я уже читал об этой настройке. Но дополнительная поездка туда и обратно для каждого подключения - это не то, что я готов платить за редкий случай ошибки подключения. Хотя я бы предпочел автоматическую очистку пула подключений, похоже, что это невозможно. Поэтому я приму решение позвонить ClearPool сам. - person cremor; 08.04.2013
comment
Первая ссылка мертва. Эквивалент для Oracle 12 находится здесь: docs.oracle.com/database/ 121 / ODPNT / featConnecting.htm # ODPNT174 - person MPelletier; 02.02.2017

Вообще говоря, вам следует избегать попыток манипулировать пулом соединений для любого поставщика ADO.NET (а также каналов WCF - в стороне). Если ваше приложение должно быть устойчивым к основным ошибкам данных (например, тайм-аутам, разорванным соединениям в пуле и т. Д.), Вам следует реализовать соответствующий уровень транзакции, чтобы гарантировать целостность данных и логику повторных попыток для повторного выполнения неудачной операции.

person Daniel P. Bullington    schedule 21.05.2011
comment
Мое приложение уже работает с транзакциями и позволяет пользователю повторить операцию. Проблема в том, что даже если пользователь повторяет попытку после ошибки соединения, операция все равно не выполняется, даже если сетевое соединение восстановлено. Похоже, что ODP.NET возвращает мне соединение, время ожидания которого истекло, пока оно находилось в пуле соединений. - person cremor; 22.05.2011
comment
Есть ли брандмауэр между приложением и БД? Я знаю, что это звучит как шаблонный вопрос, но я видел такие серьезные странности, как это, когда какое-то сетевое устройство (брандмауэр, коммутатор или маршрутизаторы) агрессивно ведет себя и закрывает соединения, даже если пул думает, что они все еще открыть. Это связано с опытом работы с SSA, DoD и другими государственными учреждениями с огромными инвестициями в Oracle и .NET. Мои 2 цента. - person Daniel P. Bullington; 01.06.2011
comment
Нет, ничего кроме переключателей. Даже роутер. - person cremor; 01.06.2011