有没有理由不在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; }
}
我意识到消息是由传输层(MSMQ)存储的,而传奇数据是通过saga持久保存到DB的。它适用于我当前的用例,并且重用该类似乎更优雅,而不是为消息创建一个,而为saga存储创建另一个。
我想知道这种方法是否有任何问题?
答案 0 :(得分:6)
我同意mookid8000所说的一切,但我还有一个细节需要补充。
你的传奇存储通常会有很多争用。为了保证一致性,传奇存储提供程序通常会对数据进行更新锁定,以保证来自同一传奇的另一条消息不会同时改变状态。
如果你使用的是默认的NHibernate saga persister(你的虚拟属性告诉我你是),那么NHibernate会使用一些假设来保存你的数据:
在任何情况下,更多表中需要更多行来分割数据所需的saga persister,使用粒度行锁锁定所涉及的行的难度就越大。有足够的争用,行锁将开始升级到页锁和表锁,然后你真的遇到了问题。
这就是为什么文档数据库真的会为saga存储发光,这就是为什么在NServiceBus 3.0中他们将RavenDB作为默认的saga persister。
在那之前,看一下我写的XML Serialization based Saga Persister,这可以为即将推出的RavenDB风格的saga persister带来一些好处。
如果你必须坚持使用NHibernate,我强烈建议你不要将你的消息与你的saga持久性解决方案紧密结合起来。我几乎保证会回来困扰你。
答案 1 :(得分:2)
如果你的异常传奇持久存在数据而没有抱怨,我想不出这种方法有什么问题 - 只要你意识到你为了两个目的重用一个类,从而引入了传奇数据之间的耦合(关于服务的私人信息)和关于字段存在,命名等的消息(本质上是公开的)
然后,如果您需要偏离消息的结构方式,则可以为所有传奇数据构建类。
PS:如果TillOrderLine
的唯一目的是在IMessage
内汇总,则Order
不需要标记为{{1}}。