GAE/P:通过 API 调用实现交易安全 [英] GAE/P: Transaction safety with API calls

查看:23
本文介绍了GAE/P:通过 API 调用实现交易安全的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设您使用交易处理 Stripe 付款并更新用户实体:

Suppose you use a transaction to process a Stripe payment and update a user entity:

@ndb.transactional
def process_payment(user_key, amount):
    user = user_key.get()
    user.stripe_payment(amount) # API call to Stripe
    user.balance += amount
    user.put()

有可能 Stripe API 调用成功但 put 由于争用而失败.然后会向用户收费,但他的帐户不会反映付款.

It is possible that the Stripe API call succeeds but that the put fails because of contention. The user would then be charged, but his account wouldn't reflect the payment.

您可以从事务中提取 Stripe API 调用,然后再进行事务,但您似乎仍然遇到同样的问题.扣款成功,但交易失败,用户账户未入账.

You could pull the Stripe API call out of the transaction and do the transaction afterwards, but it seems like you still have the same problem. The charge succeeds but the transaction fails and the user's account isn't credited.

这似乎是一个非常普遍的场景.如何正确处理这个问题?

This seems like a really common scenario. How does one properly handle this?

推荐答案

为了正确操作,事务函数需要是幂等的.所以你不能在这样的函数中进行条带调用,因为它会使其成为非幂等的.

For proper operation the transactional function need to be idempotent. So you can't make the stripe call inside such function as it would make it non-idempotent.

我会单独进行条带调用,如果 API 成功,我会调用事务函数来更新用户的帐户余额(在发生争用时可以安全地重试).

I'd make the stripe call separate and, on API success, I'd call a transactional function to update the user's account balance (which can be safely retried in case of contention).

甚至可以创建一个单独的、独立的实体来反映条带 API 调用结果?这样的实体应该没有争用的余地,因为它只被写入一次——当条带事务发生时.这将允许您:

Maybe even create a separate, independent entity to reflect the stripe API call result? Such entity should have no room for contention since it's only written once - when the stripe transaction takes place. This would allow you to:

  • 保留帐户交易的历史记录 - 指向这些实体
  • 进行一些健全性检查以查找孤立的条带交易(如果帐户交易调用即使在重试后仍因任何原因失败)并采取措施.

@thebjorn 的评论很好:多步骤方法可以使过程非常可靠:

@thebjorn's comment is a good one: a multi-step approach could make the process pretty solid:

  • 更新帐户以执行条带交易的交易功能,这也以事务方式将推送任务排入队列以执行条带 API 调用.仅当事务成功时,任务才会入队
  • 推送队列任务进行条带 API 调用(最终创建条带交易实体),并在成功时调用交易函数以更新帐户余额
  • a transactional function updating the account with the intent to execute a stripe transaction, which also transactionally enqueues a push task to perform the stripe API call. The task is enqueued only if the transaction succeds
  • the push queue task makes the stripe API call (eventually creating the stripe transaction entity) and, on success, calls the transactional function to update the account balance

这篇关于GAE/P:通过 API 调用实现交易安全的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆