2013-10-23 50 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

相關問題