NServiceBus的使用版本:2.0.0.1145
是否可以以这样一种方式配置NServiceBus主机,它消耗(订阅)他自己发布的消息?
似乎可能,但在下面的配置中,它在尝试将订阅插入SubscriptionStorage时给了我一个事务死锁异常。 当你使用DbSubscriptionStorage和超过1“NumberOfWorkerThreads”时会发生这种情况。
Could not execute command:
INSERT INTO Subscription (SubscriberEndpoint, MessageType) VALUES (@p0, @p1)
System.Data.SqlClinet.SqlException:
Transaction was deadlocked on lock resources with another process and has been chosen as the deadlock victim. Rerun the transaction.
之后NServiceBus尝试断开但失败,因为事务仍在进行中并抛出UnhandledException。
<!-- 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>
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();
以下是订阅和saga db的dbProperties:
connection.provider NHibernate.Connection.DriverConnectionProvider
connection.driver_class NHibernate.Driver.SqlClientDriver
dialect NHibernate.Dialect.MsSql2005Dialect
只要我没有将NumberOfWorkerThreads增加到1以上,一切正常。只要高于此值,它就会抛出上述错误。
我希望我没有忘记任何事情。感谢您的帮助。
答案 0 :(得分:1)
如果您希望相同的进程处理已发布的消息,最好在Bus.Publish()之后执行Bus.SendLocal()。 SendLocal()方法将在本地队列上放置一条消息,您的内部处理程序将拾取并处理它。这将摆脱你的僵局,但保持相同的语义。
答案 1 :(得分:-1)
我真的会考虑重新设计这个组件。如果你想要稳定性nservicebus给你,并且你已经打破了组件,所以处理的每个部分都在一个单独的消息处理程序中,将每个消息处理程序放在一个单独的可执行文件中,并带有一个单独的队列。如果那是不可能的,那么你就没有真正获得nservicebus的稳定性,因为你被其他一些代码锁定了,在这种情况下你应该直接调用所需的函数。
如果您只是测试它们都在一个队列中运行,那么在测试时只需将它们拆分。没有理由订阅您自己的消息 - 如果可能的话,将处理程序拆分为单独的端点,如果不可能,则直接调用函数。