У нас есть реализация 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 имеет MessagePart, который добавляется к MessageParts в его обработчике. ConfirmMessage обновляет статус конкретной MessagePart.
Это сценарий:
1) Получено первое сообщение CreateMessage. Это создает Saga в Raven и добавляет MessagePart (со статусом «1») в MessageParts.
2) Получено первое сообщение ConfirmMessage. Это обновляет статус первого добавленного MessagePart в саге на «1 2». Это видно в браузере при переходе к документу в RavenDB.
3) Получено второе сообщение CreateMessage. Это добавляет второй MessagePart к MessageParts. При просмотре данных статус первого MessagePart по-прежнему равен «1», а не «1 2», и это создает исключение параллелизма (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
Похоже, что данные Saga кэшируются для каждого типа сообщения. Это так? Есть ли решение?
ЗАМЕТКА:
Мы используем несколько IAmStartedByMessages, но когда ConfirmMessage находится перед CreateMessage, это сообщение добавляется в очередь до тех пор, пока не будет обработано CreateMessage.