Put() failing silently on HR - HELP!

43 views
Skip to first unread message

Greg

unread,
Jul 7, 2011, 12:52:41 AM7/7/11
to Google App Engine
Hi -

I've just discovered that occasionally put()s in my python HR
datastore app are failing almost silently. "Almost" because I am
seeing a "Transaction collision. Retying..." warning logged at the
time the write is supposed to happen, but nothing else - certainly no
exception is raised.

This is severely impacting the integrity of my data. I'm currently
running a remote checking script daily to fix the data, but this is a
horrible band-aid and should not be required. Either the put() should
succeed, or an exception should be raised.

Any ideas?

Cheers
Greg.

Noah McIlraith

unread,
Jul 7, 2011, 5:18:07 AM7/7/11
to google-a...@googlegroups.com
How are you fetching the stored entities? Using a query? or get()?

Robert Kluin

unread,
Jul 7, 2011, 10:51:08 AM7/7/11
to google-a...@googlegroups.com
Hey Greg,
Do you have any blind try-excepts in your code? If it is silently
failing, I'd guess something issilently catching and ignoring the
exception.

Also, as Noah mentioned, a global query immediately after a put
might not get the latest results. A get-by-key or ancestor query
will.

Robert

> --
> 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-a...@googlegroups.com.
> To unsubscribe from this group, send email to google-appengi...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/google-appengine?hl=en.
>
>

--
------
Robert Kluin
Ezox Systems, LLC

Greg

unread,
Jul 7, 2011, 10:30:28 PM7/7/11
to Google App Engine
Thanks for the suggestions. It's not an eventual consistency issue,
and I get datastore timeout exceptions so there can't be a blind try-
except. The code does a put() for one or more entities inside
run_in_transaction(), then does a raw put() for another entity. Here's
the simplified code:

logItems=''
for id in ids:
db.run_in_transaction(updateEntity,id,newTime)
logItems+=rh.logItem('B',newTime)
entity2.log+=logItems
entity2.put()

The put() in updateEntity() works, the entity2 put() fails without an
exception. The only reason I know this is that when I compare the log
data in entity2 it doesn't match the data in the updated entities.
This only happens once per 10,000 times, and I was lucky to catch two
recent cases - the time logged by the successful updateEntity() call
corresponding to the missing entity2 entry exactly matches the
"Transaction collision. Retying..." warning in the logs in both cases.

There are a few questions this raises:

1. I have assumed that the "Transaction collision. Retying..." warning
is caused by the updateEntity(), because it's in a
run_in_transaction(). But given the entity2.put() is the one failing,
perhaps that is the source? Can you get transaction collision warnings
from non-transactional put()s?

2. Surely no matter what I should get an exception if the
entity2.put() fails?

Thanks again for your help with this.

Greg.
> > For more options, visit this group athttp://groups.google.com/group/google-appengine?hl=en.

Robert Kluin

unread,
Aug 17, 2011, 1:08:40 AM8/17/11
to Google App Engine
Yes, because on HR every put happens in a transaction.

>
> 2. Surely no matter what I should get an exception if the
> entity2.put() fails?

I would expect you to, yes. Unless an earlier exception causes that
code to not run. Perhaps adding some logging would help.
Reply all
Reply to author
Forward
0 new messages