【问题标题】:Datastore Entity read (keys_only) inside ndb transactionsndb 事务中的数据存储实体读取 (keys_only)
【发布时间】:2021-01-17 22:06:12
【问题描述】:

我有一个关于在 ndb 事务中读取数据存储实体的问题。

我知道,当我们在 ndb 事务中读取实体时,该特定实体会被锁定,并且没有其他线程可以放置/更新/写入同一实体,因为这会导致争用错误。 这完全有道理。

但是,当我们在事务中只读取实体的键而不是整个实体本身时会发生什么?这可以通过在 ndb.query().fetch() 中将 keys_only 标志传递为 True 来完成 在那种情况下,实体会再次被锁定吗?

【问题讨论】:

    标签: google-app-engine google-cloud-platform google-cloud-datastore app-engine-ndb


    【解决方案1】:

    Datastore documentation for Transaction Locks 说:

    读写事务使用读写器锁来强制隔离和可串行化。

    并且它没有提及在交易期间使用keys_only 的具体情况。所以我认为这同样适用于这种情况,如果你认为你仍然在进行读取,那么这确实是有道理的,你只是忽略了数据。

    话虽如此,也许这可以在 Datastore 中进行改进,甚至可以在文档中明确说明。如果您愿意,可以考虑按照link 向 Google 提出功能请求以实施该功能。

    【讨论】:

      【解决方案2】:

      一般来说,最好根据事务的保证(可串行化)而不是实现细节来考虑事务(在这种情况下,读/写锁)。实现细节(查询的执行方式、锁定粒度、锁定的确切内容等)可能随时更改,而保证不会更改。

      对于这个特定的问题,并假设 Firestore 在 Datastore 模式下的当前实现:为确保可序列化,事务 T1 中的仅键查询会锁定查询检查的索引条目的范围。如果这样的查询返回实体 E 的键 K,则在不同事务 T2 中删除 E 的尝试必须删除 E 的所有索引条目,包括查询锁定范围内的条目。所以在这个例子中,T1 和 T2 需要相同的锁,两个事务之一将被延迟或中止。

      请注意,T2 与 T1 冲突还有其他方式:它也可能是创建一个与 T1 的查询匹配的新实体(这需要在 T1 的查询锁定的范围内写入一个索引条目)。

      最后,如果 T2 更新(而不是删除)E 的方式确实需要对 T1 查询检查的范围内的索引条目进行任何更新(例如,如果查询类似于 'select * from X where a = 5' 并且对 E 的更新不会改变它的 'a' 属性的值),那么 T1 和 T2 不会冲突(这是一种优化 - 如果这两个事务发生冲突,行为仍然是正确的,实际上对于“ Datastore Native”数据库,它们可能会发生冲突)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-05-14
        • 1970-01-01
        • 2020-07-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多