CQRS在信用卡充值中的应用(使用AKKA)

ryhaxcpt  于 2023-02-16  发布在  其他
关注(0)|答案(1)|浏览(157)

考虑到我对CQRS有点困惑,我想在下面的场景中进一步了解它。
我有一个演员,收取用户的信用卡。这样做,它联系银行外部服务,做的操作,得到一个确认结果。我想知道我如何应用这个与CQRS。
这里需要写的信息是某个特定的用户已经被收取了一定的费用。所以生成的事件是Charged(UserID,Card,Amount)。诸如此类。
问题是,我所看到的所有例子,特别是AKKA,只会在命令被验证后生成事件,这样它就被持久化在日志中,并用于更新参与者的状态。然后日志在另一边可能是红色的,这样就可以在这里创建一个阅读视图。
通常情况下,在这些例子中,update state函数有一个执行命令的逻辑,因为命令直接对应于一天结束时的状态更新。这是一个典型的BasketShoping例子:CreateOrder、AddLineItem。所有这些命令都直接在Event中翻译,其对应于Update状态函数的特定代码。
然而在这个例子中,我们需要实际联系外部服务,向用户收费,然后生成一个事件。联系外部服务不能在更新状态下完成,或者在阅读日志之后完成。这没有意义。
如何做到这一点,在哪里,什么时候,在CQRS的精神?

rta7y2nd

rta7y2nd1#

我能想到两种方法。
第一种方法很简单,命令是DoCharge(UserId, Card, Amount),收到这个命令后,调用外部支付服务,如果成功完成,就生成一个事件Charged(UserId, Card, Amount, TransactionId),并保存在日记账中。
当然,这并不是完全安全的方法,因为Actor可能在向支付服务发送请求之后,但在收到并保持成功完成的确认之前崩溃,这样就有向用户收取两次费用的风险。为了克服这种风险,你必须使你的支付操作是幂等的。下面是如何做到的。这个例子是基于经典的"RESTify Day trader"文章。我将在这里总结一下。
您需要将支付操作分为两个阶段。在第一个阶段,支付服务创建事务令牌。它仅标识事务,尚未执行任何财务操作。创建后,服务将接收标识符并将其保存在日记帐中。
在下一阶段,您执行与第一阶段的标识符关联的支付。如果您的参与者现在在中间失败,而操作在支付服务端成功执行,则交易令牌将已标记为已由支付服务处理,并且它不会让您向客户收取两次费用。现在,如果您重新启动失败的参与者,并且它尝试运行与现有交易令牌关联的支付,支付服务应该返回类似“已执行”或类似的结果。当然,最后您还将操作的结果保存在日志中。

相关问题