Проблемы с поставщиком данных Oracle .NET - Ищете другой вариант

Прежде чем я начну, я советую вам сделать глубокий вдох и понять, что это очень длинный вопрос и в нем было 3-4 проблемы в одном контексте. Так что наберитесь терпения при чтении. (напишите в комментарии, если вам что-то нужно, образец кода или что-то еще, поскольку я серьезно ищу решение).

Недавно я работал с клиентом, и он хотел иметь базу данных приложений в Oracle. Приложение было построено на ASP.NET MVC.

Мы выбрали Oracle 11g express в качестве среды разработки, и клиент подтвердил то же самое. Мы решили использовать ODAC 32bit .NET Provider который поддерживает ORM (EF). Сначала мы провели пробный пример реализации операции CRUD, и все работало нормально. Затем мы начали разработку реальных требований клиента. Через 2-3 месяца товар был готов к отправке. Так что до сих пор в ASP.NET и Oracle 11g все работало нормально. Когда мы приступили к развертыванию и UAT, мы узнали, что у клиента есть Oracle 9i для его существующей ERP, которая не соответствует версии, которую мы разработали. Поэтому мы провели поиск в Интернете, чтобы проверить, совместим ли тот же поставщик ODAC с Oracle 9i. Мы нашли ссылки, где упоминалось, что он совместим с Oracle 9i.

Мы только что перенесли базу данных на сервер Oracle 9i, соответствующим образом изменили модель EF и обнаружили следующие проблемы:

1. Транзакция не была совершена автоматически!

using (TransactionScope transaction = new TransactionScope())
{
    // some code written here
}

Тот же код работал с 11g, а при переносе на Oracle 9i он перестал работать. Транзакции не фиксировались автоматически после завершения оператора using. Мы намеренно написали transaction.commit(); в блоке using, и он заработал.

Это ожидаемое поведение?

2. Проблема с VARCHAR2 типом данных и поставщиком ODP NET. Мы создали несколько хранимых процедур в базе данных с Varchar2 и другими типами базы данных в качестве параметра. При доступе к этой хранимой процедуре с использованием стиля ADO.NET (OracleConnection, OracleCommand и OracleParameter) мы узнали, что параметры, имеющие тип данных VARCHAR2, иногда усекают данные, даже если данные, переданные в параметр, имеют размер меньше, чем заданный столбец таблицы. Он просто случайным образом удаляет количество символов с конца. Проблема также регистрируется здесь, на форуме Oracle

Мы не смогли решить эту проблему.

3. Ограничение размера встроенного запроса (количество символов). Для решения проблемы, упомянутой в пункте 2, мы поняли, что должны преобразовать эту хранимую процедуру во встроенный запрос и вызывать те, которые используют ADO.NET (старый стиль в школьные годы кодирование)! Мы преобразовали все наши хранимые процедуры в строковые сценарии и написали следующее:

OracleCommand command=new OracleCommand("Select * from something",Connection);

И использовал ту же технику для других операторов DML. Теперь все заработало, провели UAT и сделали приложение работающим. Через 10-15 дней мы обнаружили странную проблему. Если запрос (встроенный запрос) имеет размер более 4000 символов, то сервер Oracle выдает исключение, в котором говорится, что «Запрос слишком длинный для выполнения» (я не помню точно исключение или сообщение, но оно было похоже на то, что я написал) . Мы взяли образцы данных в среде разработки и отладили код и узнали, что размер SQL-запроса слишком длинный, от 32000 до 64000 символов! Мы знали, что решение этой проблемы было тем же: «Если бы мы могли каким-то образом правильно вызывать хранимые процедуры!» Но мы не можем, потому что у нас нет выбора.

В качестве решения мы воссоздали эти хранимые процедуры в базе данных и вызвали их встроенными!

OracleCommand command=new OracleCommand("BEGIN ProceduretoCall(Param1,Param2); END;",Connection);

И с тех пор работает.

Помня о вышеуказанных проблемах,

  1. Я не могу вызвать хранимую процедуру из ASP.NET обычным способом (CommandType.StoredProcedure) # проблема-1 выше
  2. Я не могу вернуть какие-либо данные, скалярное значение или возвращаемое значение из хранимой процедуры после вставки или обновления. # проблема-3 выше
  3. Я не могу использовать транзакцию на уровне кода. (Он постоянно говорит, что инициализируется распределенная транзакция, но на самом деле у меня вообще нет распределенной транзакции!)

Почему все вышеперечисленное в конце после Go Live? Это был почти кошмар проблем с Oracle, которые я решал в течение месяца, одну за другой, и это заставило меня задуматься

Действительно ли инструмент ODP.NET/ ODAC надежен?

Если нет, то какой еще вариант я могу выбрать, исходя из вашего опыта? (Пожалуйста, знайте, что ODBC также имеет аналогичную проблему с Oracle 9i).

Я, скорее всего, поработаю над подобным проектом на следующей неделе, и я подумал, что на этот раз я хочу быть готовым с лучшим подходом.


person Hiren Desai    schedule 02.03.2016    source источник
comment
Oracle 9i не поддерживается. Против него не следует разрабатывать новые приложения.   -  person Christian Shay    schedule 02.03.2016
comment
Вам следует разбить свой вопрос на части. На этот вопрос нет ответа.   -  person Patrick Hofman    schedule 03.03.2016


Ответы (1)


Я настоятельно рекомендую выделить каждый из ваших пунктов как отдельный вопрос. Каждый конкретен и имеет свои вопросы, и если все будет прямо, то будет беспорядок.

Во-вторых, я согласен с комментарием. Даже Oracle 10gR1, выпущенный в 2003 году, не поддерживается. Возможно, вам нужно принять на себя часть ответственности, не задавая этот вопрос заранее, но я также не думаю, что для вас неразумно также заявить, что они будут использовать поддерживаемую версию oracle.

Тем не менее, я сделаю быстрый удар:

  1. TransactionScope никогда не фиксируется автоматически. Вам нужно будет добавить transaction.Complete (). Единственное непредвиденное поведение - это предыдущая фиксация WAS.

  2. В упомянутой статье упоминается, что проблема решается при перекомпиляции процедур Oracle, и указывается набор исправлений Oracle, который решает проблему. В таком случае я не считаю это проблемой odp.net. Если вы хотите, вы можете вставить как подпись процесса, так и то, как вы добавляете параметр, чтобы увидеть, есть ли какие-то настройки, которые вы можете попробовать. Но опять же, я бы поставил отдельный вопрос.

3.2 - Я все равно не уверен, как вы возвращали скаляры - вам понадобится рефкурсор для параметра, и я не уверен, как создание анонимного блока изменит это. Опять же, я думаю, вам нужно опубликовать больше своего кода, в частности, как вы отправляете параметры.

3.3 - TransactionScope автоматически преобразует локальную транзакцию в распределенное соединение, если транзакция включает несколько соединений, даже если они относятся к одной и той же базе данных. Однако я не думаю, что эта функция поддерживалась до 11g, а раньше все транзакции запускались как распределенные. Однако я не уверен, что у 9i даже была такая концепция, которая могла бы объяснить странную автоматическую фиксацию, которую вы наблюдали.

ODP.net был для меня полностью надежным последние 7 лет. Тем не менее, я всегда запускал его против поддерживаемой версии oracle с установленным обновленным патчем для этой версии.

person b_levitt    schedule 03.03.2016
comment
Я полностью понимаю и думаю о разделении этих вопросов на разные вопросы, но тогда контекст не может быть получен ... как вы видите, более поздние вопросы связаны друг с другом ... Oracle 9i не поддерживается? Он поддерживается, но работает не так, как ожидалось. - person Hiren Desai; 07.03.2016
comment
Что касается других комментариев, TransactionScope выполняет автоматические коммиты, как говорит Microsoft, и это сработало для меня с MSSQL. В справочной статье вы можете пойти и еще раз проверить, что есть такие люди, как я, которые не смогли решить эту проблему даже после перекомпиляции пакета! (Ну, в моем случае у меня нет пакета, я не возражал перекомпилировать свои процедуры). Как я возвращал скаляры? С возвращаемыми значениями, как я делал в MSSQL, но поскольку хранимая процедура перестала работать, у меня не было выбора. - person Hiren Desai; 07.03.2016
comment
Я должен согласиться и перепроверить пункт 3.3 (у меня есть несколько подключений для одной и той же базы данных), так что это может быть одной из причин. Спасибо, что указали на это! - person Hiren Desai; 07.03.2016
comment
Позвольте мне уточнить детали. В ссылке, которую я разместил выше, см. Комментарий этого пользователя gdarling - oracle, который упомянул, что исправление версии базы данных с 9207 до 9208 решает проблему. В моем случае версия базы данных - 9206. У клиента есть огромная ERP, разработанная на этой версии, он ни разу не обновлял свою версию базы данных за последние 20 лет, и они не готовы рискнуть изменить свою версию. последний раз они отключили свою систему в 2003 году всего на несколько минут! Так что обновление версии базы данных для меня тоже не вариант! - person Hiren Desai; 07.03.2016
comment
Я на 100% уверен, что TransactionScope не выполняет автоматическую фиксацию. Вы должны показать мне, где scope.Complete () не требуется. - person b_levitt; 07.03.2016
comment
Сожалеем, что клиенты не могут установить исправления - это ставит вас в трудное положение для написания современного программного обеспечения с надежными результатами. Без исправлений у вас есть только обходные пути. - person b_levitt; 07.03.2016