问题 尝试使用ODP.NET在Oracle 11g中读取或写入受保护的内存


我正在开发一个应该运行很长时间的应用程序,并通过ODP.NET广泛使用Oracle(11g)数据库。

但是,偶尔会发生一次(每2或3天)ODP.NET抛出一次System.AccessViolationException,然后需要重新启动应用程序。这是我的堆栈跟踪:

Unhandled exception: System.Reflection.TargetInvocationException: Exception has been thrown by the target of an invocation. 
---> System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Oracle.DataAccess.Client.OpsSql.Prepare2(IntPtr opsConCtx, IntPtr& opsErrCtx, IntPtr& opsSqlCtx, IntPtr& opsDacCtx, OpoSqlValCtx*& pOpoSqlValCtx, string pCommandText, IntPtr& pUTF8CommandText, OpoMetValCtx*& pOpoMetValCtx, Int32 prmCnt)
at Oracle.DataAccess.Client.OracleCommand.ExecuteNonquery()

堆栈跟踪的其余部分不时不同,并且是指来自我的应用程序的内部调用。

现在,我在问这里之前做了相当多的研究,但我没有找到任何结论。许多其他人显然遇到了同样的问题,尽管根本原因似乎变化很大。我真的希望有人有这个解决方案:-)

在一个不相关的说明中,似乎此异常能够忽略我的catch {}块并导致应用程序每次发生时崩溃。那是因为它与内存损坏问题有关吗?

问候, 安德里亚

编辑:进一步的调查让我相信,值得启动“分布式事务协调器”服务并查看异常是否会被抛出。你怎么看?


13120
2017-07-01 15:50


起源

仅供参考它忽略你的try / catch块的原因是因为当代码的非托管部分崩溃时它会占用整个dot.net堆栈。 - tsells


答案:


这是一个错误。 11.1和11.2提供商有这个问题。解决此问题的唯一方法是安装11.2.0.2客户端,然后应用补丁6。


7
2017-08-23 03:57





在构建我的OracleCommand对象并添加参数时......

我发现改变自:

select.Parameters.Add("Result", OracleDbType.RefCursor);

至:

select.Parameters.Add("Result", OracleDbType.RefCursor, ParameterDirection.Output);

在11.2.0.2客户端上为我消除了这个问题。


5
2017-11-16 23:19





我们遇到了相同的AccessViolationException,因为RefCursor被声明为 输入 参数而不是 产量

command.Parameters.Add("O_RECS", OracleDbType.RefCursor, null, ParameterDirection.Input);

对于这样一个简单的错误,这是一个苛刻的信息。更改参数方向修复了错误。

command.Parameters.Add("O_RECS", OracleDbType.RefCursor, null, ParameterDirection.Output);

2
2018-04-13 15:17