On Mon, Jul 25, 2011 at 7:56 AM, 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"
>

The first part specifically refers to ancestor queries. Ancestor queries
always operate on the latest copy of the data, as they're restricted to an
entity group; regular queries don't have that guarantee.


> 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.
>

Correct, with the usual caveat about transactionality (if you're not doing
this inside a transaction, you have a potential race condition).


>
> 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.
>

Correct - but again, any update outside a transaction always has possible
race conditions.

>
> 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.
>

Do the update in a transaction, which fetches the entity, updates it, and
stores it.

-Nick Johnson

>
> 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.
>
>


-- 
Nick Johnson, Developer Programs Engineer, App Engine

-- 
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.

Reply via email to