Хост NServiceBus, который подписывается на собственные опубликованные сообщения - PullRequest
1 голос
/ 15 октября 2010

Используемая версия NServiceBus: 2.0.0.1145

Вопрос:

Можно ли настроить хост NServiceBus таким образом, чтобы он потреблял (подчинялся) свои собственные опубликованные сообщения?

Ответ:

Это кажется возможным, но в следующей конфигурации это дает мне исключение блокировки транзакции при попытке вставить подписки в SubscriptionStorage.Это происходит, когда вы используете DbSubscriptionStorage и более 1 «NumberOfWorkerThreads».

Ошибка:

Could not execute command:<br> INSERT INTO Subscription (SubscriberEndpoint, MessageType) VALUES (@p0, @p1)<br> System.Data.SqlClinet.SqlException:<br> Transaction was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.

После этого NServiceBus пытается отключиться, но завершается неудачей из-за транзакциивсе еще выполняется и выдает UnhandledException.

Как воспроизвести:

Вот мой App.Config:

<!-- Publishing Configuration -->
<MsmqTransportConfig InputQueue="test_publisher_output" ErrorQueue="test_error" NumberOfWorkerThreads="3" MaxRetries="5" />

<!-- Subscription Configuration -->
<UnicastBusConfig DistributorControlAddress="" DistributorDataAddress="" ForwardReceivedMessagesTo="">
    <MessageEndpointMappings>
        <add Messages="MessageAssembly" Endpoint="test_publisher_output" />
    </MessageEndpointMappings>
</UnicastBusConfig>

My Bus-Configuration:

var bus = Configure.With()
    .Log4Net()
    .StructureMapBuilder(container)
    .XmlSerializer()
    .MsmqTransport()
        .IsTransactional(true)
        .PurgeOnStartup(false)
    .DBSubcriptionStorage(subscriptionDbProperties, true)
    .Sagas()
    .NHibernateSagaPersister(sagaDbProperties, true)
    .UnicastBus()
        .ImpersonateSender(false)
        .LoadMessageHandlers(First<GridInterceptingMessageHandler>
            .Then<SagaMessageHandler>())
    .CreateBus()
    .Start();

и вот мои dbProperties как для подписки, так и для саги:

connection.provider      NHibernate.Connection.DriverConnectionProvider
connection.driver_class  NHibernate.Driver.SqlClientDriver
dialect                  NHibernate.Dialect.MsSql2005Dialect

Все работает хорошо, пока я не увеличу NumberOfWorkerThreads выше 1. Все выше, чем это, и это будетВыкиньте вышеуказанные ошибки.

Надеюсь, я ничего не забыл.Заранее спасибо за помощь.

Ответы [ 2 ]

1 голос
/ 15 октября 2010

Если вы хотите, чтобы тот же процесс обрабатывал опубликованное сообщение, было бы лучше сделать Bus.SendLocal () после Bus.Publish ().Метод SendLocal () поместит сообщение в локальную очередь, а ваш внутренний обработчик подберет его и обработает.Это избавит вас от тупика, но сохранит семантику.

0 голосов
/ 25 октября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...