【问题标题】:How to allow an access to the document for only one onUpdate function at the same time?如何同时只允许一个 onUpdate 函数访问文档?
【发布时间】:2021-09-27 11:53:48
【问题描述】:

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

TotalValue 以这种方式计算 - 当添加或修改销售时(onCreate / onUpdate 函数),字段 totalValue 的值是从文档中获取的,它是计算出来的(例如,增加 100)是添加了 value=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(但不是作为应用端的线程)?还有其他选择吗?

【问题讨论】:

    标签: firebase google-cloud-firestore google-cloud-functions


    【解决方案1】:

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

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


    可以还通过setting maxInstances in your code 告诉云函数不要一次运行超过一次的云函数实例。

    【讨论】:

      猜你喜欢
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      • 2012-01-05
      • 2018-03-25
      • 2017-03-20
      • 2022-09-27
      相关资源
      最近更新 更多