Oracle.DataAccess.Client.OracleException ORA-03135: соединение потеряно - PullRequest
8 голосов
/ 30 июля 2010

У меня есть служба .Net, которая подключается к базе данных Oracle при каждом запросе.Сначала все работает нормально, но после некоторого количества запросов я начинаю получать:

Oracle.DataAccess.Client.OracleException ORA-03135: connection lost contact
   at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure)
   at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteReader(Boolean requery, Boolean fillRequest, CommandBehavior behavior)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteReader()
   at MyApp.Services.OracleConnectionWithRetry.ExecuteReader(OracleCommand command)
   ...

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

Ответы [ 2 ]

12 голосов
/ 16 марта 2011

Это происходит потому, что ваш код запрашивает соединение из пула соединений Oracle, а пул соединений возвращает отключенное / устаревшее соединение с БД Oracle.ODP.NET сама не проверяет состояние соединения для соединения, отправленного клиенту.

Поэтому, чтобы быть в безопасности, либо проверяйте connection status == Open для соединения, полученного из пула, когда вы выполняете Connection.Open ()

ИЛИ

пусть ODP.NET выполнит за вас проверку, установив Validate Connection = true в строке подключения в web.config.

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

Третий вариант, который я использую, - это использование исключений.Сначала будьте оптимистичны и используйте любое соединение, возвращаемое из пула соединений.Если вы получаете ORA - 3135, запросите новое соединение и снова выполните свой запрос, как цикл while.В лучшем случае вы можете получить ваше первое соединение как действительное, и ваш запрос будет выполнен.В худшем случае все соединения в вашем пуле устарели, и в этом случае код будет выполняться N раз (где N - размер пула соединений).

2 голосов
/ 08 октября 2010

Я тоже это видел; Попробуйте отключить пул соединений с помощью «Pooling = false» в строке соединения. У меня есть теория, что пустые соединения в пуле истекают, но ODP.NET не осознает, что они истекли, а затем, когда ваше приложение захватывает одно и пытается что-то сделать, вы получаете это исключение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...