【问题标题】:Firestore idempotency for a virtual wallet虚拟钱包的 Firestore 幂等性
【发布时间】:2019-02-21 15:02:48
【问题描述】:

我又来找你们帮忙了。我有一个应用程序,您可以在其中使用信用卡为自己的虚拟钱包充值。

我的结构是追随者:

  • collection transactions/{transactionId} -- 包含所有者 UID 和充值金额。
  • 集合users/{userId}/personal/wallet包含{ funds: 0 }

我将钱包保存在personal info 的子集合中,因为我不希望其他用户看到它。

无论如何,对于transactions 集合下的新文档,我有一个名为walletSynconCreate 触发器,我从中取出金额并通过runTransaction 将其添加到用户的当前资金中。

问题是,该函数有时会针对一个文档触发 3 次……。这是一个屏幕截图。我已经记录了 transactionId(这只是一个文档),如您所见,onCreate 被处理了 3 次,因此,我的钱包充值了实际值的 3 倍。

这是我的功能代码,我在其中使用processed: true 标记任何已处理的事务,以便下次触发时可以忽略它。正如您在日志中看到的那样,processed_already 消息永远不会弹出,这意味着触发器不会在下次触发时获取新数据。

我在这里没有想法,请指教。

编辑:这是我的功能:https://pastebin.com/PRA7CbxL

【问题讨论】:

  • 正如该线程中所建议的,一种可能的解决方法是检查相应的 transactionId 是否已被处理。
  • 我很着急,没有提到我已经用一个名为processed 的字段将这些文档标记为true。无论哪种方式,它根本没有考虑到这一点。
  • 我已经浏览了 stackoverflow 上的所有幂等线程,没有一个真正解释如何解决这个问题。我唯一发现的是应该是唯一的 eventId。但由于我的已处理字段没有被考虑在内,这也无济于事。
  • 您确实需要使用该唯一的事件 ID。这是实现正确幂等性的主要工具。

标签: google-cloud-firestore


【解决方案1】:

在强大的@Doug 和提到的类似问题的帮助下,我设法弄清楚了。

毕竟,我的代码的问题在于,当我将交易标记为processed 时,我假设函数第二次/第三次触发,snapshot.data() 将是文档的值,(取我有时间意识到)它实际上是发送到数据库触发器的change 数据。我知道这听起来令人困惑,但该函数并未发送文档的值(因为您可以获取 snapshot.ref 并从那里获取数据,以便在事务中获取更新的值)。

这是我在Pastebin 上的更新功能。这是运行代码的屏幕截图:https://i.imgur.com/fbQSGT6.png

【讨论】:

    猜你喜欢
    • 2018-06-06
    • 2015-06-20
    • 2021-11-13
    • 1970-01-01
    • 2012-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多