We have a NServiceBus implementation that handles multiple message-types:
public class StateCoordinator : Saga<MessageData>,
IAmStartedByMessages<CreateMessage>,
IAmStartedByMessages<ConfirmMessage>
MessageData is something like this:
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; }
}
The CreateMessage has a MessagePart that is added to MessageParts in its handler. The ConfirmMessage updates the status of a particular MessagePart.
This is the scenario:
1) A first CreateMessage is received. This creates the Saga in Raven and adds a MessagePart (with status "1") to MessageParts.
2) A first ConfirmMessage is received. This updates the Status of the first added MessagePart in the Saga to "1 2". This is vissible in the browser when going to the document in RavenDB.
3) A second CreateMessage is received. This adds a second MessagePart to MessageParts. When looking to the Data, the status of the first MessagePart is still "1" and not "1 2" and this throws a concurrency-exception (the ActualETag does not equals the 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
It looks like the Saga-data is cached per message-type. Is this so? Is there a solution?
NOTE:
We are using multiple IAmStartedByMessages but when the ConfirmMessage is before the CreateMessage, then this message is added to a queue until the CreateMessage is handled.