2014-09-22 3 views
0

У меня есть несколько обработчиков сообщений в конкретной конечной точке, которые выполняют свою работу с базой данных SQL Azure (на данный момент все еще используется локальный экземпляр SQL 2012). У меня есть обработчик команд, который публикует 2 события, называет их X и Y. В той же конечной точке у меня есть подписчик на X и абонент на Y. Оба этих абонента внутренне используют один и тот же компонент доступа к данным, назовите это Z. Dependency инъекция настраивается для каждого вызова, а не для общего доступа.Сделки в NServicebus с использованием Azure Service Bus Transport

Компонент Z использует платформу Entity Framework 6 под занавесками. Проблема, с которой я сталкиваюсь, заключается в том, что просто открытие базы данных бросает исключение SqlException и жалуется на эскалацию MSDTC.

Я временно обернул обработчики в TransactionScope.Suppress, и это остановило ошибку, но я считаю, что мне не хватает чего-то более фундаментального.

Непросто ли конфигурировать конечную точку без транзакций? Я бы подумал, что это будет просто работать, поскольку я настроил использовать Azure Service Bus в качестве механизма транспорта. Если я это сделаю, NServiceBus все равно повторит попытку, если в обработчике сообщений будет создано исключение? (До пределов SLR - не часть вопроса, я также понимаю проблемы идемпотентности).

+0

Используете ли вы SQL Server в качестве транспорта для NServiceBus или как хранилище данных? Что касается транспорта Azure Service Bus - NSB будет повторять исключения с FLR (и SLR, если сконфигурировано), как обычно. –

+0

Это похоже на проблему с конфигурацией, но я пытаюсь понять вашу настройку (какой транспорт NServiceBus вы используете?) –

+0

SQL Server используется исключительно для хранения данных. Я использую Azure Service Bus в качестве транспорта. Я также прочитал, что если бы я сделал это не транзакционным, я бы не получил попытки FLR или SLR? Это верно. –

ответ

0

@Phil,

Во-первых, вы не должны использовать MSDTC с SQL Azure - это не поддерживается. Функция предлагается, но только under review. DTC не поддерживается на Azure. Кроме того, вы можете посмотреть на following suggestion, чтобы использовать подход SqlTransaction.

Во-вторых, транспорт, который вы используете, не имеет никакого отношения к вашему доступу к данным. Поскольку вы используете Azure Service Bus, он не будет частью вашего кода обработчика. Сделать обработчик транзакцией - заставить атомное изменение или откатить. Независимо от вашего обработчика, повторите попытку. Проблема заключается в том, что когда обработчик/конечная точка не является транзакционным, а внутри обработчика первая запись в БД преуспела, а вторая не удалась, первая запись не будет отменена. Что касается Azure Service Bus как транспорта, он не является транзакционным по своей природе (то есть без кода DTC).

+0

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

0

Какая версия NServiceBus.Azure у вас? У вас есть трассировка стека исключения? От куда это?

Мы выталкиваем отправления и публикуем вне области видимости транзакции приема, чтобы предотвратить продвижение по DTC, чтобы транзакция была локальной для SQL, поэтому я сомневаюсь, что это то, что происходит здесь.

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

Может ли это быть? Что он бросает на второй открытый?

+0

Это вполне может быть.Будет проверять и обновлять принятый ответ. –