NServicebus处理程序与自定义sqlconnection

时间:2016-08-25 18:34:28

标签: nservicebus sqlconnection sqlcommand

我有一个NServiceBus处理程序,它创建一个新的sql连接和新的sql命令。

但是,在整个过程完成之后,才会将执行的命令提交到数据库。

就像处理程序本身中存在隐藏的sql事务一样。

我将代码移动到没有nservicebus的自定义控制台应用程序中,并立即执行并保存了sql命令。与nservicebus不同,它不会在处理程序结束之前保存。

4 个答案:

答案 0 :(得分:2)

事实上,每个处理程序都包含在一个事务中,默认的事务保证依赖于DTC。这是故意的:)

如果您禁用它,那么您可能会收到重复的消息或丢失一些数据,因此必须小心。您可以使用端点配置API禁用事务,而不是使用连接字符串中的选项。

您可以在此处找到有关配置和可用保证的更多信息http://docs.particular.net/nservicebus/transports/transactions

答案 1 :(得分:0)

找到了解决方案。

在我的连接字符串中,我必须添加Enlist = False

答案 2 :(得分:0)

如@wlabaj所述,设置Enlist = False确实会确保处理程序中打开的事务与传输接收/发送消息所使用的事务不同。

然而,重要的是要注意它改变了消息处理语义。默认情况下,当使用DTC时,接收/发送和处理程序内的任何事务操作将以原子方式提交/回滚。使用Enlist = False并非如此,因此可能会为同一消息提交多个处理程序事务。将以下场景视为可能发生的示例案例:

    收到
  • 消息(运输交易开始)
  • 消息在处理程序内成功处理(处理程序事务已成功提交)
  • 传输事务失败,消息被移回输入队列
  • 第二次收到消息
  • 消息在处理程序
  • 中成功处理
  • ...

Enlist-False设置的行为在您的情况下可能是理想的行为。话虽如此,我认为值得澄清一下消息处理语义的后果是什么。

答案 3 :(得分:0)

工作单元

消息应作为单个工作单元处理。一切都成功或失败。

如果您想要执行多个工作单元,那么

  • 创建多个端点
  • 或发送多条消息

这样做的好处是可以并行处理这些内容。

请注意,创建多个处理程序不会产生此效果。同一端点上的所有处理程序 将成为同一工作单元的一部分,从而进行交易。

立即发送

如果你真的想发送一条特定的消息,当发送消息不能成为工作单元的一部分时,你可以立即发送它:

using (new TransactionScope(TransactionScopeOption.Suppress))
{
    var myMessage = new MyMessage();
    bus.Send(myMessage);
}

这对V5有效,对于其他版本,最好查看文档:

http://docs.particular.net/nservicebus/messaging/send-a-message#dispatching-a-message-immediately

网罗=假

这是一种解决方法,不得用于规避特定的事务配置,如Tomasz所解释的那样。

这可能导致数据损坏,因为在错误恢复的情况下可以多次处理相同的消息,然后再次执行相同的数据库操作。