Я не уверен, соответствует ли мое мышление Уди и др., Но я всегда понимал, что данные саги очень легкие метаданные о сообщениях, они не должны содержать много реальных сообщенийdata.
Вы могли бы иметь сагу для каждого платежного запроса и соответствующего утверждения / отмены, но давайте предположим, что банк либо требует, чтобы вы собрали их все вместе в течение рабочего дня, либо взимает с васфиксированная сумма на файл, что является обычным явлением ...
В этом случае, лежащей в основе системы обмена сообщениями (NServiceBus), которую вы, скорее всего, делаете, или должен иметь какую-то транзакционную систему, которая на самом деле отслеживание самих транзакций .Если они группируются в какой-то тип партии (то есть рабочий день), то партия должна иметь идентификатор. Это - это то, на что должна ссылаться сага, в дополнение к базовой информации о состоянии всего процесса (т.е. вы уже получили ответ от банка?).
Сервисная шинаэто не система сама по себе, это способ для независимых систем и компонентов общаться друг с другом.Саги на самом деле предназначены для удаления после завершения (через MarkAsComplete
), поэтому они действительно не место для хранения "постоянной" информации.
В моем мире данные саг выглядят примерно таквместо этого:
public class PaymentProcessingSagaData : IContainSagaData
{
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
public virtual int RequestBatchId { get; set; }
public virtual DateTime? WhenRequestBatchClosed { get; set; }
public virtual string BankRequestFileName { get; set; }
public virtual DateTime? WhenRequestFileSent { get; set; }
public virtual string BankResponseFileName { get; set; }
public virtual DateTime? WhenResponseFileReceived { get; set; }
public virtual int PaymentBatchId { get; set; }
}
Это соответствует порядку операций, например:
- Запрос отправлен в приложение, которое создает / добавляет в пакет и отправляет событие
PaymentRequested
. - Подписчик выбирает событие
PaymentRequested
и при необходимости создает новую сагу и устанавливает RequestBatchId
, которая становится идентификатором корреляции саги.Затем он устанавливает тайм-аут для закрытия бизнеса. - Обработчик тайм-аута закрывает пакет, устанавливает
WhenRequestBatchClosed
и публикует событие PaymentRequestBatchClosed
. - Подписчик получает событие
PaymentRequestBatchClosed
, создаетфайл оплаты (устанавливает BankRequestFileName
), публикует событие RequestFileAvailable
, сообщающее, что файл готов. - Подписчик получает событие
RequestFileAvailable
и инициирует процесс загрузки, который (например) передает файл по FTPсервер банка обновляет WhenRequestFileSent
и публикует событие RequestFileSent
. - Процесс мониторинга (или другой обработчик тайм-аута) обнаруживает файл ответов, обновляет
BankResponseFileName
и WhenResponseFileReceived
и публикует событие ResponseFileAvailable
. - Подписчик получает событие
ResponseFileAvailable
, обрабатывает файл, создает пакет платежей, обновляет PaymentBatchId
, а также опционально публикует итоговое событие PaymentsProcessed
и завершает сагу.
Конечно, вам не обязательно нужны эти When
поля DateTime, вы также можете легко иметь логические флаги, указывающие, какие шаги завершены.Но важно то, что ваша сага отслеживает транзакцию состояние , а не транзакцию data .
Не делайтеошибка в попытках заглушить все в сагу.Она не предназначена для того, чтобы занять место транзакционной системы, это всего лишь немного клея, чтобы скрепить все это.