Hi, On Sun, Jul 24, 2011 at 16:56, Pol <i...@pol-online.net> wrote: > Hi, > > I'm having some trouble with this article in the scope of the HR > datastore: > http://code.google.com/appengine/articles/transaction_isolation.html > > It says: > >> In a High Replication datastore the transaction is typically completely >> applied within a few hundred milliseconds after the commit() returns. >> However, even if it is not completely applied, subsequent reads, writes, and >> ancestor queries will always reflect the results of the commit() because >> these operations apply any outstanding modifications before executing. > > But then just afterwards, it also says: > >> However, if a concurrent request executes a query whose predicate (the >> 'where clause' for you SQL/GQL fans out there) is not satisfied by the >> pre-update entity—but is satisfied by the post-update entity —the entity >> will only be part of the result set if the query executes after the apply >> operation has reached Milestone B. > > "ancestor queries will always reflect the results of the commit() > because these operations apply any outstanding modifications before > executing" != "the entity will only be part of the result set if the > query executes after the apply operation has reached Milestone B" > > My understanding of this article is therefore the following (assuming > an HR datastore and that we are inside a transaction): > > 1) Using db.get() / db.put() on an entity always executes on its > latest version: no race conditions possible, period. > -> Observations in my app appears to confirm that behavior. > > 2) Using db.GqlQuery() / db.put() on entities in the same entity group > might still be subject to race-conditions: for instance, a previously > *committed* transaction modified the entities that would be returned > by the query in the later transactions, but the datastore indexes are > not up-to-date yet (or something like that), so the query doesn't see > the updated entities - even if calling db.get() directly on them would > return the versions that match the query. > -> I've reviewed my code carefully and I think I'm seeing such race > conditions in my app.
Unless your doing the fetch and db.put() within a transaction, the put could be simply overwriting the entities. Perhaps that is your issue. The query will be consistent if it is an *ancestor* query, ie the where clause specifies "ANCESTOR IS xxx". You can do the ancestor query (or a fetch by key) and put within a transaction; that should allow you to ensure consistency. > > Can Google folks confirm #2? > > And if yes, how do you effectively work around this limitation? Is > there such a thing as a flush() command? Some extra param to say > commit and wait for real completion at the end of the transaction? I'm > OK with extra latency per-entity group, but I really need to avoid > race conditions in this specific part of my app. When you do an ancestor query, get, or put, a "flush" on the entity group effectively happens before the operation. Robert > > Thanks, > > - Pol > > -- > You received this message because you are subscribed to the Google Groups > "Google App Engine" group. > To post to this group, send email to google-appengine@googlegroups.com. > To unsubscribe from this group, send email to > google-appengine+unsubscr...@googlegroups.com. > For more options, visit this group at > http://groups.google.com/group/google-appengine?hl=en. > > -- You received this message because you are subscribed to the Google Groups "Google App Engine" group. To post to this group, send email to google-appengine@googlegroups.com. To unsubscribe from this group, send email to google-appengine+unsubscr...@googlegroups.com. For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.