首页 > 解决方案 > 如何在 Actor 模型框架(例如,akka.net)中执行非幂等操作(发送电子邮件)?

问题描述

我正在研究使用演员模型框架(akka.net 与 akka.net 持久性,但我正在寻找一般案例答案)来构建“小部件订单处理工作流程”。

很标准:

  1. 客户订单小部件
  2. 付款已处理
  3. 发送给客户的电子邮件确认
  4. 将选项列表消息发送到仓库
  5. 仓库发回“小部件已发货”消息
  6. 向客户发送“您的商品已发货”电子邮件

现在假设在 4 到 5 之间发生服务器部署/重启。这将导致演员补水(假设还没有快照)。这意味着我们将再次处理付款,并重新发送已下订单的电子邮件。然而事实证明,我们的客户不喜欢这个“功能”!

使用actor模型框架时如何防止非幂等动作再次发生?

我曾考虑过单独存储“为订单数据库表处理的付款”;但这感觉就像我在与框架/范式作斗争,我想知道是否有一种“正确”的方式来做这种事情!

标签: akkaactorakka.net

解决方案


好的,事实证明这很简单。

使用 akka.net 持久性,在系统恢复后,消息会被重播。可以通过(重新)处理这些消息来重新创建正确的状态。

然而,有一个IsRestoring属性,可以检查这是第一个还是后续处理。想必其他actor模型框架也有类似的东西。

所以你做这样的事情:

private void ProcessPayment (Order message)
{
    if(!this.IsRestoring){
        //Perform non-idempotent payment process
    }
}

推荐阅读