【问题标题】:Design Patterns for Performing Multiple Server Operations as a Single Transaction将多个服务器操作作为单个事务执行的设计模式
【发布时间】:2018-07-23 16:57:45
【问题描述】:

假设您有一个 SaaS 应用并希望在用户注册时执行以下操作:

  1. 验证他们的姓名、电子邮件等
  2. 为用户创建一个Stripe客户帐户。
  3. 为新的 Stripe 客户订阅现有的 Stripe 计划。
  4. 在您的数据库中创建一条包含 Stripe 信息的用户记录。
  5. 为用户创建一个新会话。
  6. 将用户重定向到您应用的仪表板。

理想情况下,您希望所有这些都发生在一个事务中,即如果第 4 步失败,您希望撤消第 2 步和第 3 步...您不希望没有数据库记录的悬空 Stripe 客户和订阅。

您会推荐哪些设计模式来使此类多步骤/多服务流程具有事务性?

对于上下文

我正在使用 Node 中的 ES6 Promises 实现这个多步骤过程 - 伪代码如下:

async function signup_user_for_trial(req, res) {

  const {email, name, plan, password} = req.body

  if (!isValidEmail(email)) {
    throw new Error(...)
  }

  let customer = await createStripeCustomer(email)
  let subscription = await createSubscription(customer, plan)
  let user = await createDBUser(customer, name, email, password)
  let session = await createSession(req, user)

  return res.redirect('/dashboard')
}

【问题讨论】:

    标签: design-patterns stripe-payments saas


    【解决方案1】:

    我想我要做的是构建一个表来负责引用事务的所有关键部分。在您的示例中,通过Create a Customer API 端点创建客户的第 2 步将产生一个客户 ID,而通过Create a Subscription API 端点附加计划的第 3 步将产生一个订阅 ID。

    我将在您的数据库中有两个表:一个代表您的用户相对于他们的 Stripe 客户 ID,另一个代表用户是否需要“回滚”。

    一般来说,您总是会填充用户表。但是,如果您的流程在某处中断,请在“回滚”表中添加一个条目,其中包含用户 ID(或类似内容)和/或指示您是否也应该回滚任何费用的条目。有一个 cron-job 定期检查这些条目以异步执行一些关键请求:

    显然有很多方法可以做到这一点,但我认为这似乎是最简单的。

    【讨论】:

    • 使用 cron 作业定期协调失败操作的日志是一个有趣的想法。在考虑了一段时间后,我得出的结论是,没有“聪明”的方法可以做到这一点,除了手动保存日志......就像实际的 DBMS 为事务做的那样。谢谢@korben。
    猜你喜欢
    • 1970-01-01
    • 2017-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多