我有一个问答评论应用程序(类似于stackoverflow(。这些问题及其相关答案和评论在逻辑上构成 App Engine 文档中定义的实体组的一部分。
我想使用实体组/祖先路径将我的实体分组在一起,原因有两个:
- 通过将问答实体物理存储在一起来提高查询效率
- 允许我执行祖先查询,从而消除了我将答案键存储在问题实体(关系(上的需要
我不想要很强的一致性,因为它最终会引起争用。
App Engine 是始终在更新时锁定实体组,还是仅在事务中完成更新时才锁定实体组?换句话说,实体组是强制在事务中进行更新,还是仅提供使用事务的选项?
关于您选择基于祖先的方法的第一个原因 - 我认为我从未见过任何关于数据存储中物理位置的承诺 - 我想任何此类约束都会与其高可扩展性发生冲突。我不会担心,恕我直言,这种效率优化的收益(如果有的话(可以忽略不计。
您应该知道,争用与(强(一致性没有直接关系(一致性实际上归结为查询结果的准确性(。
但是,争用与同时访问同一实体组直接相关,即使是读取操作,而不仅仅是写入 - 请参阅 Google App Engine 中的争用问题。使用祖先只会使情况变得更糟,因为祖先树中的所有实体都位于同一实体组中。
出于您的第二个原因(如果我正确理解您的目标(,您无需将答案键存储到您的问题实体中或使用祖先。如果将问题键(或键 ID(存储到答案实体中,则可以通过对具有匹配问题键/ID 的答案实体进行常规(非祖先(查询来获取问题的答案。
实体组"锁定"仅在事务中可见(不,事务不会强制执行,但在尝试写入外部事务之前请三思而后行 - 会发生意外覆盖(。但请注意,此类锁定仅对冲突的写入操作有效,但对争用无效。