【问题标题】:Is a Firestore document locked when read by the server (cloud-function) in a Transaction?在事务中被服务器(云功能)读取时,Firestore 文档是否被锁定?
【发布时间】:2019-06-04 22:28:13
【问题描述】:

我知道 Firestore 对 SERVER(云功能)中的事务使用锁,如以下视频所述:https://www.youtube.com/watch?v=dOVSr0OsAoU

该视频详细解释了事务在客户端中的工作方式(并且它没有在那里使用锁),但对于服务器事务并没有做得很好。

以下哪些是正确的(关于 SERVER 事务)?:

1) 一个文档在一个服务器事务中被gets 锁定,所以在第一个事务完成之前其他服务器事务不能get 它。

2) 一个文档在一个服务器事务中被gets 锁定,但仅限于写入,因此其他服务器事务可以获取它,但在第一个事务完成之前不能修改它。

3) 在服务器事务中,文档未被gets 锁定,仅写入。

编辑:我需要权威来源(Firebase 团队中某人的视频或博客中的文档或一些参考资料)。

【问题讨论】:

    标签: firebase transactions google-cloud-firestore


    【解决方案1】:

    服务器端事务通常像客户端库一样工作,但不是该视频中提到的并发模型技术,而是以传统的锁定数据方式工作。因此,即使您对单个文档或查询使用事务,这些文档也会被锁定,直到事务完成。

    为了回答您的问题,由于来自云函数的事务正在内部进行(可能需要几毫秒),因此文档会在这段时间内被锁定。这意味着这些文件不能被任何其他交易获取或更改。

    1) 一个文档在一个服务器事务中被gets锁定,所以在第一个事务完成之前其他服务器事务无法获取它。

    正确。

    2) 一个文档被服务器事务中的gets锁定,但仅用于写入,以便其他服务器事务可以获取它,但在第一个事务完成之前不能修改它。

    另一个事务获取锁定的文档是没有意义的。为什么要尝试获取这样的文件,因为它无法更改?此外,在事务完成时,锁定的文档可能具有不同的值。在事务开始和完成之间,文档中的一些属性发生了变化。

    3) 一个文档没有被服务器事务中的gets锁定,只是写入。

    云函数运行事务后,文档被锁定,事务完成后解除锁定。

    编辑:

    另一个事务获得锁定的文档确实有意义。无法更改,但如果可以读取

    我指的是严格意义上的写作。无论文档是否被锁定,都可以读取所有文档。

    如果你只是想读取值

    如果您只是想读取值,则无需担心。读取时文档没有锁定。

    也许您需要读取一些值来决定是否更改另一个文档,甚至只是向用户显示一些信息。

    它会工作得很好。

    此外,根据事务,您不必关心文档是否在下一秒内发生变化。例如,如果用户想知道他银行账户里的金额,你可以显示一秒前的值,没问题。

    是的,没错。在读取操作方面没有任何限制,对于您的示例,是的,没关系。这也适用于我的一个项目。

    能否请您指出他们的来源?

    有很多资源可以解释传统的数据锁定方式是如何工作的。正如 Todd Kerpelman 在喜欢的视频中所证实的那样,服务器端交易就是以这种方式工作的。这种锁定的目的是服务和保护共享资源(文档)。

    我真的需要绝对确定这一点,所以我需要消息来源,或者 Firebase 团队的其他人来确认它们。

    我们还希望 Firebase 团队中的某个人花时间来看看这个,但我不确定我是否理解您的顾虑?您是否认为在进行交易时,您不会阅读文件?还是?

    【讨论】:

    • Alex,另一个事务获取锁定文档确实有意义。它无法更改,但是如果您只想读取该值,则可以读取它。也许您需要阅读一些值来决定是否更改另一个文档,甚至只是向用户显示一些信息。此外,根据事务,您不在乎文档是否在下一秒内发生更改。例如,如果用户想知道他银行账户里的金额,你可以显示一秒前的值,没问题。
    • 关于您的答案,感谢您抽出宝贵的时间来编写它们。你能指出我的来源吗?我真的需要绝对确定这一点,所以我需要消息来源,或者 Firebase 团队的其他人来确认它们。
    • 请查看我对您的 cmets 的回答。
    • 回答您的问题:我们开发了一个 Firebase 模拟器,用于测试并且运行良好。但是,我们也需要模拟服务器事务,所以我们需要确切地知道它们是如何工作的。
    • 我明白了,所以如果您需要模式信息,请告诉我。顺便说一句,好主意,祝你好运:)
    【解决方案2】:

    根据有关 Transactions and Batch writes 的 Firestore 文档,

    一个事务由任意数量的get() 操作和任意数量的写操作组成,例如set()update()delete()。在并发编辑的情况下,Cloud Firestore 会再次运行整个事务。例如,如果一个事务读取文档,而另一个客户端修改了这些文档中的任何一个,则 Cloud Firestore 会重试该事务。此功能可确保事务在最新且一致的数据上运行。

    结论:一个文档在服务器事务中没有被get()s 锁定。但是当一个文档在当前事务中为get()之后被另一个事务修改时,会导致当前事务重试,使得更新后的文档再次变为get()

    【讨论】:

    • 感谢您的回答,但是,该文档部分以“使用 Cloud Firestore 客户端库...”开头。所以这是指客户端,而不是服务器。我的问题是关于 SERVER Transactions。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-11
    • 1970-01-01
    相关资源
    最近更新 更多