Using Google App Engine's NDB datastore, how do I ensure a strongly consistent read of a list of entities after creating a new entity?
The example use case is that I have entities of the Employee kind.
- Create a new employee entity
- Immediately load a list of employees (including the one that was added)
I understand that the approach below will yield an eventually consistent read of the list of employees which may or may not contain the new employee. This leads to a bad experience in the case of the latter.
e = Employee(...)
e.put()
Employee.query().fetch(...)
Now here are a few options I've thought about:
IMPORTANT QUALIFIERS
I only care about a consistent list read for the user who added the new employee. I don't care if other users have an eventual consistent read.
Let's assume I do not want to put all the employees under an Ancestor to enable a strongly consistent ancestor query. In the case of thousands and thousands of employee entities, the 5 writes / second limitation is not worth it.
Let's also assume that I want the write and the list read to be the result of two separate HTTP requests. I could theoretically put both write and read into a single transaction (?) but then that would be a very non-RESTful API endpoint.
Option 1
- Create a new employee entity in the datastore
- Additionally, write the new employee object to memcache, local browser cookie, local mobile storage.
- Query datastore for list of employees (eventually consistent)
- If new employee entity is not in this list, add it to the list (in my application code) from memcache / local memory
- Render results to user. If user selects the new employee entity, retrieve the entity using key.get() (strongly consistent).
Option 2
- Create a new employee entity using a transaction
- Query datastore for list of employees in a transaction
I'm not sure Option #2 actually works.
- Technically, does the previous write transaction get written to all the servers before the read transaction of that entity occurs? Or is this not correct behavior?
- Transactions (including XG) have a limit on number of entity groups and a list of employees (each is its own entity group) could exceed this limit.
- What are the downsides of read-only transactions vs. normal reads?
Thoughts? Option #1 seems like it would work, but it seems like a lot of work to ensure consistency on a follow-on read.