在ndb事务中修改和读取实体

时间:2016-02-17 15:41:47

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

是否保证如果我将实体放入ndb事务中然后读取它(在相同的ndb txn中),我会得到最近编写的实体?

这里提到https://cloud.google.com/appengine/docs/java/datastore/transactions#Java_Isolation_and_consistency

  

与大多数数据库不同,查询并进入数据存储区   事务中没有看到之前写入的结果   交易。具体而言,如果在其中修改或删除实体   一个事务,一个查询或获取返回的原始版本   交易开始时的实体,如果是,则不执行任何操作   实体当时不存在。

如此裸露的Google数据存储区(没有ndb)将无法返回最近编写的实体。

但是ndb缓存了实体(https://cloud.google.com/appengine/docs/python/ndb/transactions):

  

交易行为和NDB的缓存行为可能会混淆   你,如果你不知道发生了什么。如果你在里面修改一个实体   一个交易,但尚未提交交易,然后是NDB   上下文缓存具有修改后的值但基础数据存储区   仍有未经修改的价值。

为了更清楚一点,我写了一段工作正常的代码:

@ndb.transactional()
def test():
    new_entity = MyModel()
    key = new_entity.put()
    assert key.get() is not None
test()

我的问题是如何在ndb事务中进行可靠的ndb缓存?

2 个答案:

答案 0 :(得分:2)

如果关闭缓存,您的测试失败:

class MyModel(ndb.Model):
  _use_cache = False

但它可以启用上下文缓存。 就像在文档中解释的一样。

无论如何在事务中编写和获取相同的实体是没有任何意义的。

答案 1 :(得分:0)

NDB缓存文章(https://cloud.google.com/appengine/docs/python/ndb/cache#incontext)说:

  

上下文缓存仅在单个持续时间内持续存在   线。这意味着每个传入的HTTP请求都是新的   在上下文缓存和"可见"只对处理的代码   那个要求。如果您的应用程序产生任何其他线程   处理请求时,这些线程也会有一个新的,单独的   上下文缓存。

     

上下文缓存很快;这个缓存存在于内存中。当一个NDB   函数写入数据存储区,它也写入上下文   缓存。当NDB函数读取实体时,它会检查上下文   先缓存。如果在那里找到实体,则没有数据存储区交互   发生了。

因此可以保证在ndb事务期间,上下文缓存将处于活动状态(如果您没有故意关闭缓存)。