Reputation: 115
Is it guarantied that if I put entity inside ndb transaction and then read it (in the same ndb txn), I'll get recently written entity?
Here https://cloud.google.com/appengine/docs/java/datastore/transactions#Java_Isolation_and_consistency is mentioned:
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.
So bare Google Datastore (without ndb) wouldn't return recently written entity.
But ndb caches entities (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.
To be a bit more clear I wrote a piece of code which works fine:
@ndb.transactional()
def test():
new_entity = MyModel()
key = new_entity.put()
assert key.get() is not None
test()
And my question is how is reliable ndb caching inside ndb transaction?
Upvotes: 2
Views: 744
Reputation: 115
NDB Caching article (https://cloud.google.com/appengine/docs/python/ndb/cache#incontext) says:
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.
So it is guaranteed that in-context cache will be alive during ndb transaction (if you don't turn off caching deliberately).
Upvotes: 1
Reputation: 6201
Your test will fail if you turn off caching:
class MyModel(ndb.Model):
_use_cache = False
But it's work with context caching enabled. Just like it's explained in the docs.
It does not makes any sense to write and get the same entity inside of transaction anyway.
Upvotes: 2