Попытка читать или писать защищенную память в Oracle 11g с помощью ODP.NET

Я разрабатываю приложение, которое должно работать в течение длительного времени и широко использовать базу данных Oracle (11g) через ODP.NET.

Однако бывает, что время от времени (каждые 2 или 3 дня) OSS.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 {} и приводить к сбою приложения каждый раз, когда это происходит. Это потому, что это связано с проблемами с повреждением памяти?

С уважением, Andrea

edit: дальнейшее расследование побудило меня поверить, что стоит начать работу с сервисом "Координатор распределенных транзакций" и посмотреть, не прекратится ли исключение. Как вы думаете?

Ответ 1

Это ошибка. Эта проблема возникла у поставщиков 11,1 и 11,2. Единственный способ обойти это - установить клиент 11.2.0.2, а затем применить патч 6.

Ответ 2

При создании объекта OracleCommand и добавлении параметров...

Я обнаружил, что переход от:

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

To:

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

Устранила эту проблему для меня на клиенте 11.2.0.2.

Ответ 3

Мы испытали одно и то же AccessViolationException, потому что RefCursor был объявлен как параметр input вместо Вывод.

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

Это грубое сообщение для такой простой ошибки. Изменение направления параметра устранило ошибку.

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

Ответ 4

Для всех, кто нашел эту проблему. Если у вас нет подходящего значения для BatchSize, вам может не хватить памяти. Это приводит к той же ошибке.