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

Modifying and reading entity inside ndb transaction

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

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

Unlike with most databases, queries and gets inside a Datastore transaction do not see the results of previous writes inside that transaction. Specifically, if an entity is modified or deleted within a transaction, a query or get returns the original version of the entity as of the beginning of the transaction, or nothing if the entity did not exist then.

如此简单 Google 数据存储(没有 ndb)不会 return 最近写入的实体。

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

Transaction behavior and NDB's caching behavior can combine to confuse you if you don't know what's going on. If you modify an entity inside a transaction but have not yet committed the transaction, then NDB's context cache has the modified value but the underlying datastore still has the unmodified value.

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

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

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

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

class MyModel(ndb.Model):
  _use_cache = False

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

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

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

The in-context cache persists only for the duration of a single thread. This means that each incoming HTTP request is given a new in-context cache and and is "visible" only to the code that handles that request. If your application spawns any additional threads while handling a request, those threads will also have a new, separate in-context cache.

The in-context cache is fast; this cache lives in memory. When an NDB function writes to the Datastore, it also writes to the in-context cache. When an NDB function reads an entity, it checks the in-context cache first. If the entity is found there, no Datastore interaction takes place.

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