【问题标题】:Firebase concurrent read/writeFirebase 并发读/写
【发布时间】:2020-06-05 08:55:37
【问题描述】:

我使用 Firebase 事务来获取比较值,然后更新集合中文档的值。

但是当我使用相同的数据并同时发送查询时,它们都读取相同的值,因此我对两者都进行了检查,结果我得到了一个不好的结果。 该字段减少了两次。

我的交易是:

let docRef = db.collection('X').doc('SF');
let reduceValue = 20;
let transaction = db.runTransaction(t => {
  return t.get(docRef)
    .then(doc => {
      let value = doc.data().y ;
      if (value >= reduceValue) {
        t.update(cptRef, { y:FieldValue.increment(-reduceValue) });
        return Promise.resolve('Y increased');
      } else {
        return Promise.reject('sorry y is ');
      }
    });
}).then(result => {
  console.log('Transaction success', result);
}).catch(err => {
  console.log('Transaction failure:', err);
});

谢谢。

【问题讨论】:

  • 您能否详细说明如何“同时发送查询”?请编辑您的问题。
  • 使用两个设备同时按下调用该函数的按钮

标签: javascript firebase concurrency google-cloud-firestore transactions


【解决方案1】:

如果我正确理解您的问题,您所描述的是使用 Firestore 客户端 SDK 之一执行的 Firestore Transaction 的正确行为:

  • 您调用了两次旨在递减计数器的函数;
  • 最后,计数器递减两次。

您的两个调用“同时”执行这一事实不应改变结果:计数器应递减两次。

这正是事务所确保的:在并发编辑的情况下,Cloud Firestore 再次运行整个事务,确保初始文档(在您的情况下为 db.collection('X').doc('SF'))在事务期间没有更改。如果是这种情况,它将使用新数据重试操作。

这是因为客户端 SDK 对事务使用乐观并发,因此不会锁定文档。

我建议你看下面的official video,里面有详细的解释。


您还将在此视频中看到,对于从后端执行的事务(例如使用 Admin SDK),机制是不同的:它们实现了悲观并发(在交易期间锁定文件)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-11-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多