![](/img/trans.png)
[英]What's the equivalent of Entity.all(keys_only=True).fetch(20) in NDB?
[英]Datastore Entity read (keys_only) inside ndb transactions
我有一个关于在 ndb 事务中读取数据存储实体的问题。
我知道当我们在 ndb 事务中读取实体时,该特定实体被锁定,并且没有其他线程可以放置/更新/写入同一实体,因为这会导致争用错误。 这完全有道理。
但是,当我们在事务中只读取实体的键而不是整个实体本身时会发生什么? 这可以通过在 ndb.query().fetch()中将 keys_only标志传递为 True 来完成。在这种情况下,实体会再次被锁定吗?
一般来说,最好根据它们的保证——可串行化——而不是它们的实现细节——在这种情况下,读/写锁来考虑事务。 实现细节(查询的执行方式、锁定粒度、锁定的确切内容等)可能随时更改,而保证不会更改。
对于这个特定问题,并假设 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”数据库,它们可能会发生冲突)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.