複数のメッセージ タイプを処理する NServiceBus 実装があります。
public class StateCoordinator : Saga<MessageData>,
IAmStartedByMessages<CreateMessage>,
IAmStartedByMessages<ConfirmMessage>
MessageData は次のようなものです。
public class FlowData : IContainSagaData
{
[Unique]
public Guid MappingId { get; set; }
public Guid Id { get; set; }
public string OriginalMessageId { get; set; }
public string Originator { get; set; }
public List<MessagePart> MessageParts { get; set; }
}
public MessagePart
{
public int Id { get; set; }
public string Status { get; set; }
}
CreateMessage には、そのハンドラーで MessageParts に追加される MessagePart があります。ConfirmMessage は、特定の MessagePart のステータスを更新します。
これはシナリオです:
1) 最初の CreateMessage が受信されます。これにより、Raven に Saga が作成され、MessagePart (ステータス "1") が MessageParts に追加されます。
2) 最初の ConfirmMessage が受信されます。これにより、Saga に最初に追加された MessagePart の Status が「1 2」に更新されます。これは、RavenDB のドキュメントに移動すると、ブラウザーで表示されます。
3) 2 番目の CreateMessage が受信されます。これにより、2 つ目の MessagePart が MessageParts に追加されます。データを見ると、最初の MessagePart のステータスは「1 2」ではなく「1」のままであり、これにより同時実行例外がスローされます (ActualETag は ExpectedETag と等しくありません)。
A first chance exception of type 'Raven.Abstractions.Exceptions.ConcurrencyException' occurred in Raven.Client.Lightweight
Additional information: PUT attempted on document 'flow/79a7ee20-f090-4648-9b62-a3da00d87c93' using a non current etag
サガデータはメッセージタイプごとにキャッシュされているようです。そうですか?解決策はありますか?
ノート:
複数の IAmStartedByMessages を使用していますが、ConfirmMessage が CreateMessage の前にある場合、このメッセージは CreateMessage が処理されるまでキューに追加されます。