我会直截了当地说。我正在尝试通过发送到我们银行的文件自动化信用卡付款。卡付款未经银行实时验证。银行隔夜处理付款,并在第二天发送回复文件,同时付款成功和不成功。
我有一个网络应用程序,当它接受或取消付款时,会将包含付款/取消详细信息的消息(通过Bus.Send)发送到命令消息处理器。
然后处理器(通过Bus.Publish)发布此内容供所有服务查看。
一项服务需要执行以下操作:
问题是我不知道如何在传奇中存储消息集(或其他任何内容),因为List<>'不允许作为虚拟成员。
这是当前的传奇结构:
public class PaymentRequestCancelledSagaBase : IContainSagaData
{
// the following properties are mandatory
public virtual Guid Id { get; set; }
public virtual string Originator { get; set; }
public virtual string OriginalMessageId { get; set; }
// List of all the received PaymentRequestedMessages
public virtual List<PaymentRequested> PaymentRequestedMessages;
// List of all the received PaymentCancelledMessages
public virtual List<PaymentCancelled> PaymentCancelledMessages;
}
有什么想法吗?
答案 0 :(得分:9)
我不确定我的想法是否与Udi等人一致,但我总是将saga数据理解为非常轻量级的元数据关于消息,它应该不包含太多实际内容消息数据。
你可能为每个付款请求和相应的批准/取消都有一个传奇,但我们假设银行要求您在每个工作日将它们全部批量处理,或者每个文件向您收取固定金额,这很常见......
在这种情况下,你可能做的消息系统(NServiceBus)或者 应该有某种事务系统,实际上跟踪 事务本身< / em>的。如果将它们分组到某种类型的批次(即工作日),则批次必须具有ID。除了有关整个过程状态的基本信息之外,那个是传奇应该引用的内容(即你是否从银行获得了回复?)。
服务总线本身不是一个系统,它是独立系统和组件相互通信的一种方式。实际上,Sagas一旦完成(通过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
,这将成为传奇相关ID。然后它设置关闭业务的超时。WhenRequestBatchClosed
并发布PaymentRequestBatchClosed
事件。PaymentRequestBatchClosed
事件,创建付款文件(设置BankRequestFileName
),发布RequestFileAvailable
事件,表明该文件已准备就绪。RequestFileAvailable
事件并启动上传过程(例如)将文件FTP到银行服务器,更新WhenRequestFileSent
并发布RequestFileSent
事件。BankResponseFileName
和WhenResponseFileReceived
并发布ResponseFileAvailable
事件。ResponseFileAvailable
事件,处理文件,创建付款批,更新PaymentBatchId
,并可选择发布最终PaymentsProcessed
事件并完成传奇。当然,您不一定需要这些When
DateTime字段,您可以轻松地使用布尔标志来指示哪些步骤已完成。但重要的是您的传奇跟踪事务州,而不是事务数据。
不要误以为要把所有东西都塞进一个传奇故事中。它并不意味着取代交易系统,将它们放在一起只是一些粘合剂。