在我们的一个产品中,我们使用ODP.net托管驱动程序使用存储过程从Oracle数据库中检索数据。
偶尔(大约每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或大于缓冲区长度减去offset参数的值)。
异常不能手动复制,并且在执行具有不同参数的不同程序时永远不会引发异常(即它是随机的)。
配置: ODP.net托管驱动程序版本:4.121.1.0 .net框架4.5 Oracle服务器版:Oracle Database 11g企业版11.2.0.4.0版(Linux)
有没有人经历过这个问题?有没有可用的修复程序?
提前致谢!
答案 0 :(得分:3)
在使用Oracle支持打开票证后,他们发送了托管ODP.net库的非官方更新版本,似乎解决了这个问题。
希望修复程序应该是下一个ODAC版本的一部分(今天最新版本将从2015年10月开始)。
如果您在应用程序中看到此错误,可能是由于托管ODP.net库中的错误,而不是您使用它的方式。
答案 1 :(得分:0)
在ODP.NET Oracle.ManagedDataAcess random ORA-12570 errors阅读类似问题之后,看起来它实际上是一个汇集问题。显然,答案是在连接字符串中设置Pooling=false
,或者找出可以打开的线程数以及连接在Oracle变得过多之前可以打开多长时间。这是该问题的作者发布的答案:
为了找到启用了池的最佳配置,我创建了一个测试应用程序来启动50个线程(每个线程每50ms执行1次测试),并减少默认池值,直到错误停止。通过这种方式,我可以获得最佳配置,稳定,没有任何错误。
显然它并不适用于每个服务器,但这是我的最终连接字符串配置:
Pooling=true;Min Pool Size=1;Connection Lifetime=180;Max Pool Size=50;Incr Pool Size=5