Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/81.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
重用NServiceBus消息和saga数据_Nservicebus - Fatal编程技术网

重用NServiceBus消息和saga数据

重用NServiceBus消息和saga数据,nservicebus,Nservicebus,是否有任何理由不在saga数据中重用NServiceBus消息(IMessage)?我的意思是有这样的信息: public class Order : IMessage { public virtual List<TillOrderLine> OrderLines { get; set; } } public class TillOrderLine : IMessage { ... } public class OrderProcessingSaga : Saga

是否有任何理由不在saga数据中重用NServiceBus消息(
IMessage
)?我的意思是有这样的信息:

public class Order : IMessage
{
   public virtual List<TillOrderLine> OrderLines { get; set; }
}

public class TillOrderLine : IMessage { ... }
public class OrderProcessingSaga : 
    Saga<OrderProcessingSagaData>, 
    IAmStartedByMessages<Order> { ... }

public class OrderProcessingSagaData : ISagaEntity
{
   public virtual Guid Id { get; set; }
   public virtual string Originator { get; set; }
   public virtual string OriginalMessageId { get; set; }

   // The message data is stored by the saga here.
   public virtual Order Order { get; set; }
}
公共类顺序:IMessage
{
公共虚拟列表命令行{get;set;}
}
公共类TillOrderLine:IMessage{…}
然后在传奇和传奇数据中使用它,如下所示:

public class Order : IMessage
{
   public virtual List<TillOrderLine> OrderLines { get; set; }
}

public class TillOrderLine : IMessage { ... }
public class OrderProcessingSaga : 
    Saga<OrderProcessingSagaData>, 
    IAmStartedByMessages<Order> { ... }

public class OrderProcessingSagaData : ISagaEntity
{
   public virtual Guid Id { get; set; }
   public virtual string Originator { get; set; }
   public virtual string OriginalMessageId { get; set; }

   // The message data is stored by the saga here.
   public virtual Order Order { get; set; }
}
公共类OrderProcessingAga:
传奇故事
IAmStartedByMessages{…}
公共类OrderProcessingSagaData:ISagaEntity
{
公共虚拟Guid Id{get;set;}
公共虚拟字符串发起者{get;set;}
公共虚拟字符串OriginalMessageId{get;set;}
//消息数据由saga存储在这里。
公共虚拟订单{get;set;}
}
我意识到消息是由传输层(MSMQ)存储的,而saga数据是通过saga持久化到DB的。它适用于我当前的用例,重用类似乎比为消息创建一个类和为saga存储创建另一个类更优雅


我想知道这种方法是否有缺陷?

如果你的surrent saga持久化器毫无怨言地持久化数据,我想不出这种方法有什么错——只要你意识到你在为两个目的重用一个类,从而在saga数据之间引入耦合(这是服务私有的)以及关于字段显示、命名等的消息(本质上是公共的)

然后,如果需要改变消息的结构方式,您可以为所有的saga数据构建类


PS:
TillOrderLine
不需要标记为
IMessage
,如果它的唯一目的是在
订单中聚合

,我同意mookid8000所说的一切,但是我还有一个细节要补充

在您的saga存储上通常会有很多争议。为了保证一致性,saga存储提供商通常会对数据设置更新锁,以确保来自同一saga的另一条消息不会同时改变状态

如果您使用的是默认的NHibernate saga persister(您的虚拟属性向我表明您是),那么NHibernate会使用一些假设来保存您的数据:

  • saga数据中的复杂类型将导致数据库列遵循ComplexTypePropName\u ChildPropertyName语法(或其左右-从内存操作)。因此,您的saga数据仍将包含在一个表中的一行中
  • 如果您的saga数据中有一个列表,它显然必须创建一个新表来存储列表项。现在,您的saga数据包含在一个主行和多个细节行中。
    • 为了使NHibernate映射此属性,您的集合类型还必须具有名为Id的Guid属性,这意味着您不能存储原语列表,并且您的TillOrderLine类(公共消息的一部分)将需要此Id属性,该属性对您服务的业务目的毫无意义
  • 如果您的saga数据(顺序,基本上是重用的消息)中有一个复杂的类型,并且它本身包含一个列表(订单行),我不知道在您的情况下会发生什么
在任何情况下,saga persister需要将数据拆分成的表越多,就越难使用细粒度行锁锁定相关行。有了足够的争用,行锁将开始升级为页锁和表锁,然后您就真的遇到了问题

这就是为什么文档数据库在saga存储中会大放异彩,这就是为什么在NserviceBus3.0中,他们将RavenDB作为默认的saga持久化器

在此之前,请看一看我写的,它可以为您今天的应用程序带来即将推出的RavenDB风格的saga持久器的一些好处


如果您必须坚持使用NHibernate,我强烈建议您不要将您的消息与您的saga持久性解决方案紧密结合。我几乎可以保证,它会回来缠着你。

谢谢你,穆基德,这是有道理的。我也没有注意到TillOrderLine中的IMessage-很好的回答:)谢谢你的回答David,我感谢你的观点。我也很期待3.0版的RavenDB传奇。这更自然。我的用例是我自己网站的订购场景。可悲的是,我并不期望由于高争用率而导致性能下降:(说真的,它实际上是一个单机站点,上面有web和合作伙伴订单和履行。我正在更多地使用NSB来简化设计和开发——哦,还有测试。