【问题标题】:nServiceBus : How do I make a non-transactional call to a database from within the context of a transactional operationnServiceBus:如何从事务操作的上下文中对数据库进行非事务调用
【发布时间】:2012-03-22 01:59:46
【问题描述】:

我们的拓扑概览:

网站向 nServiceBus 服务器发送命令,该服务器接受命令,然后发布正确的发布/订阅事件。该服务还具有消息处理程序,可以对 DB 执行一些处理以响应命令,例如:

1 个用户在网站上注册 2 网站向另一台服务器上的 nServicebus 服务发送 nServicebus 命令。 3 nServicebus 服务器有一个处理该特定类型命令的处理程序,该处理程序将某些内容记录到数据库并发送一封欢迎电子邮件

自从建立这种架构以来,我们开始在数据库上遇到死锁。我已将其追溯到数据库服务器上的 MSDTC。如果我在数据库服务器上关闭该服务,nServicebus 开始抛出错误,这对我来说表明 nServiceBus 已经在事务中登记数据库更新。

我不希望这种情况发生,我想自己处理失败的数据库,我只希望事务确保消息传递到我的 nServicebus 代理服务。我不希望从网络一直到通过 2 个服务器到数据库再返回的事务。

有什么建议吗?

编辑:这篇文章提供了一些线索,但我不完全确定这是继续的正确方法..NServiceBus - Problem with using TransactionScopeOption.Suppress in message handler

EDIT2:我们希望数据库在事务范围之外工作的原因是,目的是在另一台服务器上“异步”处理这些命令,以免降低网站速度和/或导致用户等待对于这些长时间运行的聚合命令。如果数据库在事务范围内,是否会在向分销商发出原始命令时阻止网站上的执行?对于这种情况,是否有更好的 nServicebus 架构?我们希望命令快速触发并将控制权返回给网站,以便用户可以快速继续,而不必等待我们长时间运行的 DB 命令,该命令正在更新聚合计数和发送电子邮件等。

【问题讨论】:

    标签: nservicebus nservicebus-distributor


    【解决方案1】:

    我不建议让数据库在 NServiceBus 事务的上下文之外工作。相反,请尝试降低事务的隔离级别。这可以通过调用来完成:

    .IsolationLevel(System.Transactions.IsolationLevel.ReadCommited)

    在流畅的配置中。在 v2.6 中,您必须将其放在 .MsmqTransport() 之后。在 v3.0 中,您几乎可以将这个调用放在任何地方。

    对 EDIT2 的回应:

    只要使用 NServiceBus 就可以实现不降低网站速度的目标,无论其他服务器上运行的事务级别如何。使用事务是为了保证消息在失败的情况下不会丢失,并且您不必编写自己的重复数据删除逻辑。

    【讨论】:

    • 感谢您的回答 Udi。你为什么不推荐呢?这些特定的 DB 命令有点像一时兴起就忘记了,如果它们偶尔对我们不起作用也没关系。我们使用 nSvcBus(在这些命令的情况下)只是将工作从 Web 服务器卸载到另一台服务器的一种方式。
    • 我们希望数据库在事务范围之外工作的原因是,这里的目的是在另一台服务器上“异步”处理这些命令,以免减慢网站速度,请参阅我的“ Edit2' 上面
    猜你喜欢
    • 2013-12-22
    • 2015-09-15
    • 2022-10-03
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多