【问题标题】:How can I use a transaction while performing a multi-location update in Firebase?如何在 Firebase 中执行多位置更新时使用事务?
【发布时间】:2017-01-10 21:26:56
【问题描述】:

在我的 Firebase 数据库中,我需要同时对两个位置进行两次写入。我对这两个位置都有规则,以确保用户不能在没有同时写入另一个位置的情况下在那里写入。

对这些位置之一的写入需要是增量/减量。当然,这必须通过事务来完成,否则我不能保证用户不会覆盖其他用户对同一节点的同时递增/递减更新。

问题是,我找不到任何关于将多位置更新与事务相结合的文档。这是不可能的吗?

【问题讨论】:

    标签: firebase firebase-realtime-database


    【解决方案1】:

    没有。事务在单个节点上运行。

    这意味着,如果您想运行多位置事务,则基本上必须在树中的“最低级别共享节点”处运行该事务。这绝不是一个好主意。

    另一种方法是使用服务器端安全规则来保护您的多位置写入。有关这方面的示例,请参阅 Is the way the Firebase database quickstart handles counts secure?,它本质上是使用安全规则构建比较和设置操作。

    【讨论】:

    • 为什么最低节点的交易“几乎不是一个好主意”?
    • 由于这个问题是关于一次调用更新多个位置,这意味着 JSON 树中的“最低级别共享节点”可能高于单个实体。这意味着资源争用的可能性更大,从而降低了事务的可扩展性。
    • 哦,是的。感谢您的回复。这是有道理的。
    【解决方案2】:

    现在可以通过引入ServerValue.increment() 将多路径更新与事务结合起来

    例子:

    Map<String, Object> postLikeUpdate = new HashMap<>();
    postLikeUpdate.put("postLikedBy/" + postId + "/" + userId, true);
    postLikeUpdate.put("likesCount/" + postId, ServerValue.increment(1));
    FirebaseDatabase.getInstance().getReference().updateChildren(postLikeUpdate);
    

    Link to release notes

    【讨论】:

    • 如果我需要增加的值是String类型怎么办? ServerValue.increment() 方法不适用于这种情况。有其他选择吗?
    • 您是否要增加保存为字符串的整数?如果是,我建议您将其存储为整数而不是字符串。它会让你的工作轻松很多。
    • 是的,我的问题就是这样。问题是该值之前已经作为字符串存储在数据库中。现在,我需要更新数据库,但这真的很麻烦。
    • 我认为对字符串字段使用普通事务并编写云函数以在字符串更新时更新整数字段会更好。此外,使用多路径更新来更新新更新中的整数字段。稍后,您可以完全逐步淘汰字符串字段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-02-18
    相关资源
    最近更新 更多