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.

Reply via email to