我们拓扑的快速概述:
网站向nServiceBus服务器发送命令,该服务器接受命令然后发布正确的发布/订阅事件。此服务还具有消息处理程序,可以响应命令对数据库执行某些处理,例如:
1个用户在网站上注册 2网站将nServicebus命令发送到另一台服务器上的nServicebus服务。 3 nServicebus服务器具有该特定类型命令的处理程序,该命令将某些内容记录到数据库并发送欢迎电子邮件
自从建立这种架构以来,我们开始在数据库上遇到死锁。我已将其追溯到数据库服务器上的MSDTC。如果我在数据库服务器上关闭该服务,nServicebus开始抛出错误,这对我来说表明nServiceBus已经在事务中登记了数据库更新。
我不希望这种情况发生,我想自己处理数据库失败,我只希望事务确保将消息传递给我的nServicebus代理服务。我不希望从Web到2个服务器再到数据库并返回。
有什么建议吗?
编辑:这篇文章提供了一些线索,但我不完全确定这是正确的继续进行方式.. NServiceBus - Problem with using TransactionScopeOption.Suppress in message handler
EDIT2:我们希望数据库在事务范围之外工作的原因是意图是在另一台服务器上“异步”处理这些命令,以免减慢网站速度和/或导致用户等待这些长时间运行的聚合命令。如果数据库在事务范围内,那么在原始命令被触发到分发者的位置阻止网站执行吗?这种情况是否有更好的nServicebus架构?我们希望命令能够快速启动并将控制权返回给网站,以便用户可以快速继续操作,而不必等待我们运行较长的DB命令,即更新聚合计数和发送电子邮件等。
答案 0 :(得分:2)
我不建议让DB在NServiceBus事务的上下文之外工作。相反,请尝试降低事务的隔离级别。这可以通过调用:
来完成.IsolationLevel(System.Transactions.IsolationLevel.ReadCommited)
在流畅的配置中。你必须把它放在v2.6中的.MsmqTransport()之后。在v3.0中,您几乎可以在任何地方拨打此电话。
对EDIT2的回应:
使用NServiceBus将实现不降低网站速度的目标,无论在其他服务器上运行的事务级别如何。事务的使用是为了保证消息在发生故障时不会丢失,并且您不必编写自己的重复数据删除逻辑。