2009-11-20 2 views
1

У меня есть служба WCF, которая использует ODP.NET для чтения данных из базы данных Oracle. Служба также записывает в базу данных, но косвенно, так как все обновления и вставки достигаются с помощью более старого уровня бизнес-логики, который я получаю через COM +, который я завершаю в TransactionScope. Более старый уровень подключается к Oracle через ODBC, а не ODP.NET.Что такое хороший способ справиться с «асинксом»?

У меня есть проблема в том, что, поскольку Oracle использует две фазы фиксации, и потому, что старший бизнес-слой с помощью ODBC и не ODP.NET, сделка иногда возвращается на TransactionScope.Commit() до того, как данные действительно доступны для чтения из служебного уровня.

Я вижу a similar post about a Java user having trouble like this, а также на переполнение стека.

Представитель Oracle posted that there isn't much I can do about this проблемы:

Это может быть связано с тем, как OLETx ITransaction :: Commit() метод ведет себя. После того, как фаза 1 2PC (то есть фаза подготовки), если все успешно, фиксация может быть возвращена, даже если ресурсы менеджеров фактически не совершили. В конце концов, успешная «подготовка» - это гарантия того, что менеджеры ресурсов не могут произвольно прекратить после этого пункт. Таким образом, даже если менеджер ресурсов не мог совершить, потому что не получил «совершить» уведомление из MSDTC (из-за сбоя сказать в связи), запрос на совершение компонента возвращает успешно. Если вы выберете строки из таблицы, вы сразу можете увидеть , иногда видите, что фактическое совершение происходит в базе данных после того, как у вас уже есть . Ваш выбор будет , поэтому не вижу новых строк из-за последовательной семантики чтения. Существует . Мы ничего не можем с этим поделать в Oracle , поскольку «фиксация успеха после успешной фазы 1» - это часть реализации MSDTC.

Итак, мой вопрос заключается в следующем:

Как я должен идти о работе с возможной задержкой («asyc» по названию) проблемы выяснения, когда вторая часть 2PC на самом деле происходит, поэтому я могу быть уверен, что данные, которые я вставил (косвенно), действительно доступны для выбора после возврата вызова Commit()?

Как большие системы справляются с тем, что данные могут быть не готовы к немедленному чтению?

+0

Вы пробовали, что предложено в этой ссылке? Перемещение на odp.net 11.1.07.20 и Oracle 11. – tuinstoel

+0

Хотел бы я просто обновить, но версия Oracle не в моем распоряжении. Бизнес-уровень еще не готов к 11 и не будет в ближайшее время. –

ответ

1

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

В этих условиях самым простым подходом является подход «понимаемый, мы думаем». Ваш запрос был понят, но вы на самом деле не знаете результата, и это то, что вы говорите пользователю. Да, во всех разумных условиях запрос будет завершен, но при некоторых условиях операторы могут фактически выбрать вмешательство в транзакцию вручную (и, возможно, вызвать эвристический ущерб при этом.)

Чтобы сделать еще один шаг, вы можете начать новую транзакцию и выполнить некоторые запросы, чтобы увидеть, есть ли данные. Теперь, если вы заполняете экран результатов, вы, естественно, будете делать такие, как запрос. Вопрос будет в том, что делать, если ожидаемых результатов не будет. Так что еще раз скажите пользователю: «Ваш последний запрос обрабатывается, нажмите« Обновить », чтобы узнать, полно ли он». Или повторите попытку автоматически (мне не нравится автоматическая повторная попытка - предпочитайте обучать пользователя, что это эффективно асинхронная операция.)

+0

Да. Как правило, 3-секундный спящий режим более чем достаточно, но гораздо медленнее, чем Commit(), фактически (почти сотня мс отклика, практически). Возможно, я должен посмотреть, чтобы ответ callback службы WCF был также асинхронным и спал, пока данные не будут готовы. –

+1

Можно ли увидеть, что данные есть? Вы можете вставить увеличивающееся число через COM + и запросить это число через ODP.NET. – tuinstoel

+0

Tuinstoel ... это точно мой следующий мозговой штурм! Я мог бы добавить какой-то «маркер» в своей транзакции - отдельный INSERT, о котором я знаю только, что идет прямо перед фиксацией. Когда я могу это прочитать, я знаю, что данные из общей транзакции доступны для чтения? –

Смежные вопросы