【问题标题】:Are firestore transactions re-executed when the doc to be updated is removed?当要更新的文档被删除时,firestore 事务是否会重新执行?
【发布时间】:2021-12-11 11:41:29
【问题描述】:

想象一下这个数据库结构:

/users(collection)
   userId/ (doc)
      likes/ (collection)
         postId1 (doc)
         postId2 (doc)
  

我正在实现一个喜欢/不喜欢帖子的功能。

为此,我正在运行一个事务,其中我get 使用该事务的类似状态(isLiked),以便执行此(喜欢)或那个(不喜欢)。

点赞操作时,需要将点赞的帖子添加到点赞用户的likes子集合中。

但是...如果在类似操作期间删除了用户的文档(即喜欢帖子)(在 UI 中我有一个用于删除用户个人资料的部分)怎么办?

如果我这样做:

transaction.create(`users/${userId}/likes/${postId}`, denormalizedPostData);  

交易是否会检测到用户文档的删除?

如果没有,如果我在删除用户的文档时也删除了用户的喜欢/子集合怎么办?

deleteUserDoc(userDocRef);
deleteFullCollection(userLikesRef, batchSize);

transaction.create(`users/${userId}/likes/${postId}`, data); 

检测到“更改”(删除文档)并重新执行事务?

我问这个是因为我知道我们需要确保读取位于事务主体中的写入之前,以便在读取文档发生更改时重新执行事务......但是,这种情况呢?

我害怕重新创建用户文档,因为只是使用 transaction.create() 操作将文档附加到用户喜欢的集合。


我应该在事务的顶部做一个额外的阅读吗?

transaction.get(userRef); // Just to ensure the re-execution

【问题讨论】:

    标签: javascript firebase google-cloud-firestore


    【解决方案1】:

    如果您通过事务处理程序读取文档,然后在同一个处理程序中对其进行修改,则 Firestore SDK 会将该文档的事务前状态和事务后状态发送到服务器。这允许服务器随后检测文档是否在事务期间被修改,包括它是否被删除。

    【讨论】:

    • 我不太喜欢在事务中添加额外的读取,因为我不使用处理程序中读取的数据,而且读取的文档被多个用户频繁更新,并且在某些情况下,这会产生重复的交易,因此会产生额外的成本(并且事情失败的可能性更大(想象在交易执行期间在短时间内对该文档进行大量更新)。
    • 顺便说一句,我已经意识到这是一个非常极端的情况,但它可能会发生,留下一些孤立的文档来执行事务逻辑(因为没有读取文档的状态(注意消除))。这是 NoSQL 中的正常情况吗?如果不是,我们是否应该在事务中读取所有可能改变我们特定功能逻辑状态的可擦除文档?仍然不必使用这些文档中的数据?
    • 如果您的事务处理程序没有读取文档,服务器将无法检测到该文档已被删除。如果不阅读您希望数据库检查的文档,就无法检测到这种情况。
    猜你喜欢
    • 1970-01-01
    • 2015-12-02
    • 2019-07-20
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多