繁体   English   中英

ndb 事务中的数据存储实体读取(keys_only)

[英]Datastore Entity read (keys_only) inside ndb transactions

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

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

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

事务锁数据存储文档说:

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

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

话虽如此,也许这可以改进到 Datastore 中,甚至可以在文档中明确说明。 如果您愿意,您可以考虑打开一个功能请求,让 Google 通过点击此链接来实施该功能。

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

对于这个特定问题,并假设 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM