18

在我们的一款产品中,我们使用 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 正在使用无效的大小参数(<=0 或大于缓冲区的长度减去偏移参数的值)调用System.Net.Sockets.Socket.Receive 。

该异常不能手动重现,并且在执行具有不同参数的不同过程时永远不会引发(即它是随机的)。

配置:ODP.net 托管驱动程序版本:4.121.1.0 .net framework 4.5 Oracle 服务器版本:Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 (Linux)

有没有人已经遇到过这个问题?有没有可用的修复程序?

提前致谢!

4

2 回答 2

4

在向 Oracle 支持开票后,他们发送了托管 ODP.net 库的非官方更新版本,似乎解决了这个问题。

希望修复应该成为下一个 ODAC 版本的一部分(今天可用的最新版本是 2015 年 10 月)。

如果您在应用程序中看到此错误,可能是由于托管 ODP.net 库中的相同错误,而不是您使用它的方式。

要考虑的另一件事是,在执行长请求期间,网络基础设施中的某些东西是否会中断空闲的 tcp/ip 连接,如本 SO answer中所述。

于 2016-03-14T16:10:41.610 回答
1

在阅读了ODP.NET Oracle.ManagedDataAcess random ORA-12570 errors上的类似问题后,它似乎实际上是一个池化问题。显然,答案是要么Pooling=false在连接字符串中设置,要么找出可以打开多少线程以及连接可以打开多长时间,然后Oracle 无法处理它。这是该问题的作者发布的答案:

为了找到启用池的最佳配置,我创建了一个测试应用程序来启动 50 个线程(每个线程每 50 毫秒执行 1 次测试),并减少默认池值直到错误停止。通过这种方式,我能够获得最佳配置,稳定,没有任何错误。

显然它并不适用于每个服务器,但这是我最终的连接字符串配置:

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

于 2016-10-19T19:30:03.860 回答