使用 Google App Engine 的 NDB 数据存储,如何确保在创建新实体后对实体列表进行高度一致的读取?
示例用例是我有 Employee 类型的实体。
- 创建一个新的员工实体
- 立即加载员工列表(包括添加的员工)
我了解以下方法将最终一致地读取可能包含或不包含新员工的员工列表。在后者的情况下,这会导致糟糕的体验。
e = Employee(...)
e.put()
Employee.query().fetch(...)
现在这里有几个我想过的选择:
重要的限定词
我只关心为添加新员工的用户读取的一致列表。我不在乎其他用户是否有最终一致的阅读。
假设我不想将所有员工都放在 Ancestor 下以启用强一致的祖先查询。在成千上万的员工实体的情况下,5 次写入/秒的限制是不值得的。
我们还假设我希望写入和读取列表是两个单独的 HTTP 请求的结果。从理论上讲,我可以将写入和读取都放在一个事务中(?),但那将是一个非常非 RESTful API 端点。
选项1
- 在数据存储中创建一个新的员工实体
- 此外,将新员工对象写入内存缓存、本地浏览器 cookie、本地移动存储。
- 查询数据存储以获取员工列表(最终一致)
- 如果新员工实体不在此列表中,请将其从 memcache / 本地内存添加到列表(在我的应用程序代码中)
- 将结果呈现给用户。如果用户选择新的员工实体,则使用 key.get() 检索实体(强一致)。
选项 2
- 使用事务创建新员工实体
- 查询数据存储以获取事务中的员工列表
我不确定选项 #2 是否真的有效。
- 从技术上讲,之前的写事务是否在该实体的读事务发生之前被写入所有服务器?或者这不是正确的行为?
- 事务(包括 XG)对实体组的数量有限制,并且员工列表(每个都是其自己的实体组)可能会超过此限制。
- 只读事务与普通读取相比有什么缺点?
想法?选项#1 似乎可行,但要确保后续阅读的一致性似乎需要做很多工作。