在NDB(Python的Google App Engine数据存储库)中自动使用缓存是否会使事务模型失效?

时间:2017-07-11 20:08:26

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

Google Cloud Datastore的一个主要卖点是它在实体组内提供了强大的一致性。

  

Cloud Datastore确保密钥和祖先查询的实体查找始终能够获得强一致的数据。

     

[数据存储区适用于]基于ACID属性的交易,例如,将资金从一个银行账户转移到另一个银行账户。

NDB library是从Google App Engine for Python访问数据存储区的文档化方式。

但是,默认情况下,NDB library uses caching会加快结果。使用的缓存是一个"上下文缓存"和memcache。但是这些缓存都不能与数据存储区进行事务更新。因此,似乎必须放弃重要的一致性属性(强调我的):

  

提交事务时,其上下文将尝试从memcache中删除所有此类实体。 但请注意,某些故障可能会阻止这些删除。

我对此的理解是否正确?也就是说,在默认配置中使用NDB库时,即使在实体组内也没有一致性保证?

如果我是对的,这是一个大问题。

它牺牲了数据存储区的最大特性。所有这些关于一致性和ACID事务的文档。在Google IO上谈论如何使用实体组来获得一致性。甚至是研究论文。悄悄地,在文档的一个小角落里,在最随意的句子中,我了解到我没有在默认配置中获得这些属性。

这令人难以置信的误导。我相信大多数人都没有见过这个。大多数实现可能期望实体组内的ACID事务,但他们没有得到它。这些是生产代码中的严重错误。

这是实施和文档的重大失败。默认情况下永远不应该牺牲速度的一致性。一致性是实体组的重点。如果实现执行了这个意想不到的事情,它会如此戏剧性地改变语义,那么文档应该让它变得非常清晰。

1 个答案:

答案 0 :(得分:2)

据我所知,如果您获得了没有使用事务缓存的实体,那么您就可以对数据进行修改。

直接数据存储区按键读取是一致的。因此,如果您希望在读取时获得强一致的结果,则需要在需要时禁用ndb缓存。否则你会得到最终的一致性如果缓存失效成功或缓存过期/逐出。

您还可能希望在事务完成后使用ndb.delete()_use_datastore=False从缓存中手动删除实体,以确保缓存是干净的。