如何允许同时只有一个 onUpdate 函数访问文档?

How to allow an access to the document for only one onUpdate function at the same time?

我有一个应用程序,每个销售都在 Tracking 集合中注册为文档。 另一个集合是Actuals。每个用户都有当月的 totalValue 字段的存储文档。

TotalValue 以这种方式计算 - 当添加或修改销售时(onCreate / onUpdate 函数)字段 totalValue 的值是从文档中获取的,它是计算的(例如增加 100,因为添加了价值 = 100 的新销售),然后用新值推回该文档。 (事实上,还有很多其他字段需要计算,我正在更新整个文档,但让我们举个例子,仅包含 totalValue。) 代码如下所示:

exports.updateActuals = functions.region(util_1.getFunctionRegion()).firestore
  .document(`${trackingCollectionName}/{id}`)
  .onUpdate((change) => {
  const service = new TargetService();
  if (<TrackingDto>change.after.data().isDeleted) {
    return service.getAndDeleteFromActuals(change.before.id, <TrackingDto>change.before.data())
    .then((actual: ActualsDto) => admin.firestore().doc(`${actualsCollectionName}/${actual.id}`).set(actual.data))
    .catch(er => error(er))
  } else {
    return service.getAndUpdateActuals(change.before.id, <TrackingDto>change.after.data(), <TrackingDto>change.before.data())
    .then((actual: ActualsDto) => admin.firestore().doc(`${actualsCollectionName}/${actual.id}`).set(actual.data))
    .catch(er => error(er));
  }
});

如果用户在在线模式下工作,这个 onUpdate 函数就像一个魅力。 当用户在离线模式下工作时会出现此问题。当他切换回在线模式时,他在离线模式下所做的所有销售都将发送到 firebase。因此,例如,那些注册的销售将同时触发 10 个 onUpdate 函数。这意味着他的“Actuals”集合中的文档将由 10 个 onUpdate 函数进行编辑。这会导致计算错误,因为它们共享相同的值(totalValue 字段)。 问题示例:

  1. ...
  2. 总价值 = 100
  3. onUpdate_1取totalValue=100加10
  4. 总价值 = 110
  5. onUpdate_2 取 totalValue=110 加 20
  6. onUpdate_3取totalValue=110加30
  7. 总价值 = 140
  8. ...

有没有办法强制 onUpdate 等到特定文档不被使用或延迟将销售文档添加到 firebase(但不是作为应用程序端的线程)?还有其他选择吗?

如果字段的新值取决于其当前值,您应该始终use a transaction - or an atomic increment operation以防止出现现在的问题。

在这种情况下,我会使用 admin.firestore.FieldValue.increment(10),它确保数据库本身将读取-递增-写入值,从而防止您现在看到的问题。


可以 还通过 setting maxInstances in your code.[=14= 告诉 Cloud Functions 永远 运行 一次 Cloud Functions 实例多次]