It's unclear to me where I should be posting this question. I've posted it 
to stack overflow in case that is more appropriate, however the nature of 
the question goes against the SO guidelines.

http://stackoverflow.com/questions/30233093/app-engine-mechanics-of-creating-a-unique-entity-if-it-doesnt-exist

On Wednesday, 13 May 2015 13:59:57 UTC+1, Francis Stephens wrote:
>
> We have an issue where we want to lazily create an entity if it does not 
> exist. There is some discussion going on about how to do this and I would 
> like to clarify some things around app engine transactions. I will limit my 
> query to single entity group transactions.
>
> I am using Go in my examples, but I hope the code is clear enough for 
> non-Go programmers.
>
> My understanding is that a transaction, on a single entity group, will 
> succeed only if the entity group is not modified externally during the 
> transaction. The 'entity group timestamp' indicating when an entity group 
> was changed is stored in the root entity of the entity group. So during a 
> transaction the current 'entity group timestamp' is read and the 
> transaction can only succeed if it hasn't changed by the end of the 
> transaction.
>
>  key := datastore.NewKey(c, "Counter", "mycounter", 0, nil)
>  count := new(Counter)
>  err := datastore.RunInTransaction(c, func(c appengine.Context) error {
>    err := datastore.Get(c, key, count)
>    if err != nil && err != datastore.ErrNoSuchEntity {
>      return err
>    }
>    count.Count++
>    _, err = datastore.Put(c, key, count)
>    return err
>  }, nil)
>
>
> In the example above (taken from 
> https://cloud.google.com/appengine/docs/go/datastore/transactions) there 
> are two non-error cases, I can see.
>
> 1: The Get succeeds and the 'entity group timestamp' on the counter can be 
> used to ensure no other transactions update the counter during this 
> transaction.
> 2: The Get fails with ErrNoSuchEntity and the Put is used to store the 
> counter for the first time.
>
> In the second case it is possible that another identical transaction is 
> running. If both transactions' Get return ErrNoSuchEntity how does the 
> datastore ensure that only one put succeeds? I would expect there to be no 
> 'entity group timestamp' in the datastore to test against?
>
> Does the transaction know that it needs to test for the non-existence of 
> the counter in order for the Put and the entire transaction to succeed?
>
> Is there a chance in this case for two transactions to succeed and for one 
> Put to overwrite the other?
>
> If there is documentation, or videos etc, around the mechanism that 
> controls this I would love to read it.
>
> Thanks in advance.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Google App Engine" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-appengine+unsubscr...@googlegroups.com.
To post to this group, send email to google-appengine@googlegroups.com.
Visit this group at http://groups.google.com/group/google-appengine.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/google-appengine/39fce7cf-fa5a-464f-821e-0826f8fdb500%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to