Ensuring a given key does not exists prior to "put"

35 views
Skip to first unread message

Mike Gleason jr Couturier

unread,
Aug 23, 2011, 10:39:26 PM8/23/11
to Google App Engine
Hi,

Given the nature of the "put" function (low level hrd API), how can I
atomically put a new entity without overwriting an existing one if the
keys are chosen by the users (String values)?

Let's say I have 2 simultaneous users that creates at the same time an
entity of kind "User" with the custom key "johndoe" (because the user
name is the key), I don't want the second one to overwrite the
first...

I don't want to have a property for the username since I'll have the
same "unique index" problem.

Is a transaction with a:
1) get
2) catch EntityNotFoundException
3) put
4) commit

enough to ensure consistency ?

Thanks

Mike Gleason jr Couturier

unread,
Aug 23, 2011, 11:23:44 PM8/23/11
to Google App Engine
I've done this, I just wan to have a second opinion:

Entity entity = new Entity("User", "mike" /*username*/);
Transaction tx = datastore.beginTransaction();

try {
datastore.get(entity.getKey());
return false; // error, already in hrd
} catch (EntityNotFoundException e) {
datastore.put(entity);
tx.commit();
return true;
} finally {
if (tx.isActive()) {
tx.rollback();
}
}

Seems a bit overkill but we need consistency right? :)

Thanks

On Aug 23, 10:39 pm, Mike Gleason jr Couturier

Mike Gleason jr Couturier

unread,
Aug 24, 2011, 12:12:55 AM8/24/11
to Google App Engine
And let's say I do it on a property, is this would be enough?

Query q = new Query("User').setKeysOnly();
q.addFilter("Email", Query.FilterOperator.EQUAL, "jo...@doe.com");

Transaction tx = datastore.beginTransaction();

if
(datastore.prepare(q).countEntities(FetchOptions.Builder.withDefaults())
> 0)
{
tx.rollback();
return false;
}

datastore.put(entity);
tx.commit();
return true;


On Aug 23, 11:23 pm, Mike Gleason jr Couturier

Robert Kluin

unread,
Aug 24, 2011, 2:12:55 AM8/24/11
to google-a...@googlegroups.com
If you want it to be unique you'll need to use the keyname, like your earlier idea. Fetch by key, if it doesn't exist you're ok to create it.


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

Mike Gleason jr Couturier

unread,
Aug 24, 2011, 2:42:17 PM8/24/11
to Google App Engine
I'll do as you suggest, thanks!

On Aug 24, 2:12 am, Robert Kluin <robert.kl...@gmail.com> wrote:
> If you want it to be unique you'll need to use the keyname, like your earlier idea. Fetch by key, if it doesn't exist you're ok to create it.
>
> Robert
>
> On Aug 24, 2011, at 0:12, Mike Gleason jr Couturier <mikegleaso...@gmail.com> wrote:
>
>
>
>
>
>
>
> > And let's say I do it on a property, is this would be enough?
>
> >            Query q = new Query("User').setKeysOnly();
> >            q.addFilter("Email", Query.FilterOperator.EQUAL, "j...@doe.com");

John OBrien

unread,
Aug 26, 2011, 10:28:53 AM8/26/11
to google-a...@googlegroups.com
Reply all
Reply to author
Forward
0 new messages