Firestore——关于事务和锁定的一些疑惑

Firestore - Some doubts about Transactions and locking

我在优惠券系统上使用 Cloud Functions,当用户验证他的邮件地址时,该系统会向用户分配优惠券。

对于我的设计,我有一个 /coupons 集合,其中预装了很多优惠券。

用户调用 HTTP firebase 函数验证他的邮件地址,在此我想将优惠券分配给用户从优惠券集合中选择一张优惠券集合,通过优惠券集合上名为“userId”的字段进行查询。

查询示例:

const pickOne = () => {
    return firestore
        .collection('coupons')
        .where('userId', "==", 'none')
        .limit(1)
}

我知道 Firestore 交易。

我的想法(如果可能的话)是调用 pickOne 作为事务 get() 函数的参数,并在其上写入值“userId”,然后关闭并提交事务。

我的疑问与锁定系统有关:是否可以避免并发用户拥有相同的优惠券?

是的,您可以在事务中执行此类查询,以有效地为用户查找单个文档,将其 ID 写入其中,并防止在具有相同查询的其他事务中再次使用它。它仅适用于后端 SDK(如 nodejs),不适用于客户端 SDK。我在其他项目中也做过类似的事情。

详情见API documentation

您唯一需要注意的是,在高写入压力下,事务可能会因 retried 次数过多而失败。在这种情况下,您将不得不在代码中显示错误或手动重试。