2013-10-23 35 views
1

我有两个消息,clientChangeMes​​sage(负责创建客户端)和clientContractChangeMEssage(负责客户端的预订细节)。现在在我的数据库中,一个客户不能创建,直到它有客户合同,反之亦然。在我的本地系统上,一切工作正常,即如果首先获取客户端更改消息,我将其存储在传奇中,并等待客户端合同消息,当到达时,传奇执行这两个消息。但在我的测试机器上,当客户端发生变化消息时,它会被存储在传奇中,但当客户端合同发生变化时,传奇并不会发现客户端会改变传奇故事,从而产生另一个传奇故事。我尝试了与我的测试人员尝试的完全相同的消息,它在我的机器上运行,并且无法弄清楚可能会出现什么问题。我正在使用乌鸦数据库持久性。 (抱歉,我不能想粘贴这方面的任何代码)佐贺错误nservicebus使用乌鸦db持久

ClientSagaState

public class ClientSagaState:IContainSagaData 
    { 
     #region NserviceBus 
     public Guid Id { get; set; } 
     public string Originator { get; set; } 
     public string OriginalMessageId { get; set; } 
     #endregion 

     public Guid ClientRef { get; set; } 

     public ClientMessage ClientChangeMessage { get; set; } 

     public ClientContractChangeMessage ClientContractChange { get; set; } 


    } 


    public class ClientSaga:Saga<ClientSagaState>, 
      IAmStartedByMessages<ClientChangeMessage>, 
      IAmStartedByMessages<ClientContractChangeMessage> 
     { 

     public override void ConfigureHowToFindSaga() 
      { 

       ConfigureMapping<ClientChangeMessage>(s => s.ClientRef, m => m.EntityRef); 
       ConfigureMapping<ClientContractChangeMessage>(s => s.ClientRef, m => m.PrimaryEntityRef); 
      } 

     public void Handle(ClientChangeMessage message) 
      { 

       if (BusRefTranslator.GetLocalRef(EntityTranslationNames.ClientChange, message.EntityRef.Value) != null) 
       { 

        GetHandler<ClientChangeMessage>().Handle(message); 
        CompleteTheSaga(); 
        return; 
       } 
       HandleServiceUserChangeAndDependencies(message); 
       //MarkAsComplete(); 
       CompleteTheSaga(); 
      } 

      public void Handle(ClientContractChangeMessage message) 
      { 
       var state=this.Data; 
       //Some handling logic 
       //Check if client is not in database then store the state 
       state.ClientContractChange=message; 
       state.ClientRef =message.PrimaryEntityRef; 
       //if client is in the data base then 
       MarkAsComplete(); 


     } 

感谢,

+0

传奇数据和传奇映射的代码至少是有帮助的。 –

回答

1

因为你映射到通过ClientRef财产撒加的数据,你需要告诉持久性(在这种情况下是Raven),这个属性是独一无二的。可能发生的情况是,在某些情况下(归结为竞争条件),第二条消息在Raven索引上执行的查询将检索陈旧数据,假定没有传奇数据并创建新数据。

这应该可以解决您的问题:

[Unique] 
public Guid ClientRef { get; set; } 

有了这些信息,乌鸦传奇留存将创建基于此属性的附加文件(因为装载凭身份证在乌鸦是完全原子),从而使第二条消息一定会找到它。

如果您正在使用NHibernate等其他持久性媒介,则将使用相同的属性来构建该列上的唯一索引。基于评论

唯一性约束的文件,你的传奇数据

编辑将是完全一致的,所以这取决于传入邮件的时间,3两一件事会发生。

  1. 该消息是真正到达,并进行处理,所以没有数据佐贺找到的第一个消息,因此它被创建。
  2. 该消息是第二个到达,所以它寻找传奇数据,找到它,并成功处理。
  3. 第二条消息到达非常接近第一条消息,所以它们都在同一时间在不同的线程中处理。这两个线程查看传奇数据并没有发现任何东西,所以他们都开始处理。第一个完成的成功并保存其传奇数据。完成第二次尝试保存传奇数据的人,但发现虽然一直在工作,但其他线程已经移动了它的奶酪,所以Raven抛出了一个并发异常。您的消息返回队列并重试,并且现在存在传奇数据,重试的行为就像场景#2。
+0

因此,让我们说,不知怎的,乌鸦数据库并没有返回所需的传奇,我的程序开始创建一个具有相同唯一ID的新传奇,那么乌鸦数据库不会抛出异常,我的信息可能会丢失。或者这种情况不会出现 – sagar

+0

编辑回答。 –

+0

由于我的测试人员至今没有遇到任何问题,因此我将此标记为已回答。谢谢 – sagar

相关问题