【问题标题】:synchrozing firebase database access同步firebase数据库访问
【发布时间】:2018-10-22 22:54:40
【问题描述】:

我有一个 firebase 数据库实例,我想为某个节点添加一个计数器。

每次用户运行特定操作时,我都想增加节点值。如何在不出现同步问题的情况下做到这一点?如何使用谷歌功能做到这一点?

例如:

database{
node {
counter : 0
}

}

在某个时间 3 个不同的用户读取计数器上的值,并尝试增加它。当它们在同一时间读取时,它们都读取“0”并递增到“1”,但在执行结束时所需的值应该是“3”,因为它被读取了 3 次

==================更新===================

@renaud 指出使用事务来保持已保存数据的同步,但我还有另一种情况,我也需要在读取端完成同步:

例如。 用户读取实际值,据此执行不同的操作并通过增加一个来完成...

在类似环境的 sql 中,我会为此编写一个过程,因为无论用户将如何处理信息,我都会通过递增一个来完成

如果我确实理解@renaud 的回答正确,那么在这种情况下,4 个不同的用户同时读取数据库将获得 0 作为当前值,然后在事务更新时最终存储的值将是 4,但在客户端每个用户就读0

【问题讨论】:

    标签: firebase firebase-realtime-database google-cloud-functions


    【解决方案1】:

    在这种情况下,您必须使用事务,请参阅 https://firebase.google.com/docs/database/web/read-and-write#save_data_as_transactionshttps://firebase.google.com/docs/reference/js/firebase.database.Reference#transaction

    事务将“​​确保与同时写入同一位置的其他客户端没有冲突。”

    在云函数中,您可以按照以下几行编写代码,例如:

    ....
    const counterRef = admin
      .database()
      .ref('/node/counter');
    
    return counterRef
      .transaction(current_value => {
        return (current_value || 0) + 1;
      })
      .then(counterValue => {
        if (counterValue.committed) {
          //For example update another node in the database 
          const updates = {};
          updates['/nbrOfActionsExecuted'] = counterValue.snapshot.val();
          return admin
            .database()
            .ref()
            .update(updates);
        }
      })
    

    如果您只想更新计数器,则只需执行以下操作(因为事务返回 Promise,如上面提到的第二个链接中所述):

    exports.testTransaction = functions.database.ref('/path').onWrite((change, context) => {
      const counterRef = admin
        .database()
        .ref('/node/counter');
    
      return counterRef
        .transaction(current_value => {
          return (current_value || 0) + 1;
        });
    });
    

    请注意,在第二种情况下,我使用实时数据库触发器作为触发器示例。

    【讨论】:

    • 我添加了更多细节,请检查
    • 如文档中所述“如果另一个客户端在您的新值成功写入之前写入该位置,则使用新的当前值再次调用您的更新函数,并重试写入。”因此,通常对于您有 4 人的情况,当第一人写入该位置(在他读取了值之后)时,将重试其他 3 人正在进行的交易。待续……
    • ... 继续。在任何情况下,您都必须考虑 a/ 写入数据库的异步特性和 2/ 触发 Cloud Function 可能存在延迟的事实。请注意,您也可以直接从客户端前端更新您的计数器,也可以通过调用事务来更新。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-03-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-18
    • 2018-07-28
    • 1970-01-01
    相关资源
    最近更新 更多