This is actually more complicated than it sounds in appengine because
there are no unique indexes. The only way to enforce a unique
username is to use a transaction. The username must be the primary
key of the entity. The rough pseudocode is something like this:
start transaction
load entity with the username
if there is an entity
abort and return duplicate error
else
create the entity
commit the transaction
if the commit fails
abort and return duplicate error
else
everything is great!
Jeff
There's a really good explanation of how it all works in Ryan Barett's
"Under The Covers Of The Google App Engine Datastore" talk:
http://sites.google.com/site/io/under-the-covers-of-the-google-app-engine-datastore
If you're going to watch one I/O session ever, this is the one to
watch. I've gone over it multiple times - it really really helps!
Jeff
2010/6/9 Jaroslav Záruba <jarosla...@gmail.com>:
GAE has a builtin optimistic concurrency management of transactions.
If someone committed a change to your entity before your commit, your
commit will fail.
There's a really good explanation of how it all works in Ryan Barett's
"Under The Covers Of The Google App Engine Datastore" talk:
http://sites.google.com/site/io/under-the-covers-of-the-google-app-engine-datastore
On Thu, Jun 10, 2010 at 5:58 AM, Jeff Schnitzer <je...@infohazard.org> wrote:GAE has a builtin optimistic concurrency management of transactions.
If someone committed a change to your entity before your commit, your
commit will fail.That's what confuses me. How can Datastore tell I'm committing entity that has been modified meanwhile when I'm creating new one.
It will, but the very short version (as I vaguely remember it) is
this: Whenever an entity is written, the timestamp that lives at the
root of the entity group is updated. When a transaction starts, it
has a time... and when a commit is made, the transaction start time is
compared against the last update time. If the entity group timestamp
is newer than your transactions start time, you get rejected.
Something like that, at any rate. Crap, now I need to watch that
video yet again...
> Yeah, that's the video where Ryan says we're not charged for indexes.
> ("Those were the days..." :))
> Seems like I wasn't careful enough and should watch it once again. I'm on
> it!
:-)
Jeff
2010/6/9 Jaroslav Záruba <jarosla...@gmail.com>:
>> has been modified meanwhile when I'm creating new one. Does it compare keys
> That's what confuses me. How can Datastore tell I'm committing entity that
> others have created since my txn.begin() when I call txn.commit()? Hopefully
> the video makes that clear for me. :)
It will, but the very short version (as I vaguely remember it) is
this: Whenever an entity is written, the timestamp that lives at the
root of the entity group is updated. When a transaction starts, it
has a time... and when a commit is made, the transaction start time is
compared against the last update time. If the entity group timestamp
is newer than your transactions start time, you get rejected.
Something like that, at any rate. Crap, now I need to watch that
video yet again...
It is explained here:
http://sites.google.com/site/io/under-the-covers-of-the-google-app-engine-datastore
(you might want to look at the slides that he skipped, starting with #55)
The short version:
TransactionA reads Entity123
TransactionB writes Entity123
TransactionB commits
TransactionA writes Entity123
TransactionA commits - and fails because timestamp of Entity123 changed
Jeff