synchronized in the cloud?

204 views
Skip to first unread message

Halm Reusser

unread,
Jun 16, 2011, 5:18:25 AM6/16/11
to Google App Engine
Hi,

we have a service which - in one transaction - does a read and a write
to the datastore. We have to assure, that no other request calls the
same service as long another thread is in there. In a simple Java app,
I just would mark the method as synchronized, but in a distributed
manner, that wouldn't work.

Are there any suggestion, how to implement such a locking a clean and
safe way?

Thanks in advance!

Ernesto Oltra

unread,
Jun 16, 2011, 7:46:00 AM6/16/11
to google-a...@googlegroups.com

Prashant Gupta

unread,
Jun 16, 2011, 10:01:11 AM6/16/11
to google-a...@googlegroups.com
I can think of two approaches:

1. Let all threads read the data (in parallel) and use transaction to update the data. Transaction will fail for all the thread except for one. Threads with failed transaction will again read data, recompute the things and try to update the data again.

2. Implement a global locking scheme - Make a dummy entity with a field of type boolean. Take true == "lock acquired" & false == "lock free". A thread which is trying to update the data will have to acquire the lock before reading data. To acquire a lock a thread will try to set lock = true, using transaction. If lock is already taken, thread will wait for the locking thread to release the lock.

In the second case, number of datastore reads can be reduced by caching lock entity in memcache.

--
Prashant

Halm Reusser

unread,
Jun 16, 2011, 10:47:18 AM6/16/11
to Google App Engine
Ernesto,

thanks, I had my whole transaction in a spring-tx transaction, which i
hoped is the same (due to isolation level SERIALIZED) as described in
http://code.google.com/intl/en/appengine/docs/java/datastore/transactions.html,
but doesn't work. Probably, have to try it with entity manager
direct.

On Jun 16, 1:46 pm, Ernesto Oltra <ernestoka...@gmail.com> wrote:
> Memcache and Datastore transactions could help a lot:
>
> http://code.google.com/intl/en/appengine/docs/java/datastore/transact...
>  http://code.google.com/intl/en/appengine/docs/java/memcache/

Halm Reusser

unread,
Jun 16, 2011, 10:50:18 AM6/16/11
to Google App Engine
Hi Prashant,

thanks.

On Jun 16, 4:01 pm, Prashant <antsh...@gmail.com> wrote:
> I can think of two approaches:
>
> 1. Let all threads read the data (in parallel) and use transaction to update
> the data. Transaction will fail for all the thread except for one. Threads
> with failed transaction will again read data, recompute the things and try
> to update the data again.

Well, sounds as a reasonable solution. Nevertheless if the suggestion
of Ernesto works, looks cleaner for me...

>
> 2. Implement a global locking scheme - Make a dummy entity with a field of
> type boolean. Take true == "lock acquired" & false == "lock free". A thread
> which is trying to update the data will have to acquire the lock before
> reading data. To acquire a lock a thread will try to set lock = true, using
> transaction. If lock is already taken, thread will wait for the locking
> thread to release the lock.
>
> In the second case, number of datastore reads can be reduced by caching lock
> entity in memcache.

I tried it with global lock in memcache, but there's no atomic test
and set function, so it does not work, or am I missing things out?

Rodrigo Pinho Pereira De Souza

unread,
Jun 16, 2011, 11:19:17 AM6/16/11
to google-a...@googlegroups.com
Please, someone from Google take a look on this.

I have an app, which uses google protorpc ( bookcalc.appspot.com )

This app was working fine until yesterday, but around 10pm( est
time ), it stopped working.

The logs say:
exceptions.ImportError: Can not import service_handlers

The code is:
from protorpc import service_handlers

The protorpc is just a folder inside my application, so I assume that
this folder was removed someway.

I will redeploy my application, and if this solves the problem, it
will indicate that there is a serious problem with GAE.

Thanks,
Rodrigo Pinho Pereira de Souza

Prashant Gupta

unread,
Jun 16, 2011, 1:58:12 PM6/16/11
to google-a...@googlegroups.com
In second case, you have to use datastore only to store lock entity and perform transactions. If there are lots of threads waiting for lock to be free (polling datastore), there will be lots of unnecessary datastored reads. If the thread which acquires/releases the lock, update the lock entity in memecache also and waiting threads check lock entity from memcache and then check datastore (if cache entity says that the lock is not taken), lots of datastore reads can be saved.

--
Prashant

Rafe Kaplan

unread,
Jun 16, 2011, 4:55:28 PM6/16/11
to Google App Engine
this problem was caused when ProtoRPC was deployed as part of the
App Engine runtime. The quickest solution for you is to make a small
hack that will allow to continue to use your original version:

http://groups.google.com/group/google-protorpc-discuss/browse_thread/thread/d7e3749420168a5b

However, the main problem is that a few weeks ago, service_handlers
were moved in to the protorpc.webapp module. What you need to do in
this case is change your service_handler import from:

from protorpc import service_handlers

to

from protorpc.webapp import service_handlers.

I would recommend that fix your imports and use the latest version
of ProtoRPC rather than relying on older versions.

On Jun 16, 8:19 am, Rodrigo Pinho Pereira De Souza
Reply all
Reply to author
Forward
0 new messages