Подтвердить что ты не робот

Управляемый драйвер ODP.net выбрасывает ORA-12570: Сетевой сеанс: Неожиданная ошибка чтения пакета

В одном из наших продуктов мы извлекаем данные из базы данных Oracle, используя хранимые процедуры, используя управляемый драйвер ODP.net.

Время от времени (примерно каждые 1000 запросов) мы получаем следующее исключение:

(ORA-12570: Network Session: Unexpected packet read error)
---> Oracle.ManagedDataAccess.Client.OracleException: ORA-12570: Network Session: Unexpected packet read error
---> OracleInternal.Network.NetworkException: ORA-12570: Network Session: Unexpected packet read error
---> System.ArgumentOutOfRangeException: Specified argument was out of the range of valid values.
Parameter name: size
   at System.Net.Sockets.Socket.Receive(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, SocketError& errorCode)
   at OracleInternal.Network.ReaderStream.ReadIt(OraBuf OB, Int32 len)
   --- End of inner exception stack trace ---
   at OracleInternal.Network.ReaderStream.ReadIt(OraBuf OB, Int32 len)
   at OracleInternal.Network.ReaderStream.WaitForReset()
   at OracleInternal.Network.OracleCommunication.Reset()
   at OracleInternal.TTC.TTCExecuteSql.ReceiveExecuteResponse(Accessor[]& defineAccessors, Accessor[] bindAccessors, Boolean bHasReturningParams, SQLMetaData& sqlMetaData, SqlStatementType statementType, Int64 noOfRowsFetchedLastTime, Int32 noOfRowsToFetch, Int32& noOfRowsFetched, Int64& queryId, Int32 longFetchSize, Int32 initialLOBFetchSize, Int64[] scnFromExecution, Boolean& bAllPureInputBinds, DataUnmarshaller& dataUnmarshaller, MarshalBindParameterValueHelper& marshalBindParamsHelper, Boolean bDefineDone, Boolean& bMoreThanOneRowAffectedByDmlWithRetClause)
   --- End of inner exception stack trace ---
   at Oracle.ManagedDataAccess.Client.OracleException.HandleError(OracleTraceLevel level, OracleTraceTag tag, Exception ex)
   at OracleInternal.TTC.TTCExecuteSql.ReceiveExecuteResponse(Accessor[]& defineAccessors, Accessor[] bindAccessors, Boolean bHasReturningParams, SQLMetaData& sqlMetaData, SqlStatementType statementType, Int64 noOfRowsFetchedLastTime, Int32 noOfRowsToFetch, Int32& noOfRowsFetched, Int64& queryId, Int32 longFetchSize, Int32 initialLOBFetchSize, Int64[] scnFromExecution, Boolean& bAllPureInputBinds, DataUnmarshaller& dataUnmarshaller, MarshalBindParameterValueHelper& marshalBindParamsHelper, Boolean bDefineDone, Boolean& bMoreThanOneRowAffectedByDmlWithRetClause)
   at OracleInternal.ServiceObjects.OracleCommandImpl.ExecuteNonQuery(String commandText, OracleParameterCollection paramColl, CommandType commandType, OracleConnectionImpl connectionImpl, Int32 longFetchSize, Int32 lobPrefetchSize, OracleDependencyImpl orclDependencyImpl, Int64[]& scnFromExecution, OracleParameterCollection& bindByPositionParamColl, Boolean& bBindParamPresent, Boolean isFromEF)
   at Oracle.ManagedDataAccess.Client.OracleCommand.ExecuteNonQuery()

Кажется, что ODP.net вызывает System.Net.Sockets.Socket.Receive с недопустимым параметром размера (< = 0 или больше длины буфер минус значение параметра смещения).

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

Конфигурация: Версия управляемого драйвера ODP.net: 4.121.1.0 .net framework 4.5 Версия сервера Oracle: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 (Linux)

Кто-нибудь уже испытал эту проблему? Есть ли какие-либо исправления?

Спасибо заранее!

4b9b3361

Ответ 1

После открытия билета с поддержкой Oracle они отправили неофициальную обновленную версию управляемой библиотеки ODP.net, которая, похоже, исправила проблему.

Надеемся, что исправление должно быть частью следующей версии ODAC (последняя из доступных сегодня - с октября 2015 года).

Если вы видите эту ошибку в своем приложении, это, вероятно, связано с той же ошибкой в ​​управляемой библиотеке ODP.net, а не с тем, как вы ее используете.

Ответ 2

После прочтения аналогичного вопроса в ODP.NET Oracle.ManagedDataAcess случайных ошибок ORA-12570, похоже, что это проблема пула. По-видимому, ответ заключается либо в установке Pooling=false в строке подключения, либо в том, чтобы узнать, сколько потоков может быть открыто и как долго соединение может быть открыто до того, как станет слишком много для обработки Oracle. Это был ответ автора этого вопроса:

Чтобы найти лучшую конфигурацию с включенным пулом, я создал тестовое приложение для запуска 50 потоков (каждый из которых выполнял 1 тест каждые 50 мс) и уменьшал значения пула по умолчанию до тех пор, пока ошибка не была остановлена. Таким образом, я смог получить оптимальную конфигурацию, стабильную и без ошибок.

Очевидно, что это не относится к каждому серверу, но это моя окончательная конфигурация строки соединения:

Pooling=true;Min Pool Size=1;Connection Lifetime=180;Max Pool Size=50;Incr Pool Size=5