mchr
mchr

Reputation: 6251

What is the correct way to atomically increment a counter in App Engine?

I am using Java on Google App Engine and I am most familiar with the JDO datastore interface. I am trying to implement a simple download counter which stores its data in the App Engine datastore.

I am only expecting a few thousands downloads/month so the update rate for my counter will be pretty low. I am therefore not interested yet in sharding the counter.

Pragmatically I could probably ignore locking and accept that I would occasionally lose an update. However, I would like to know what the right way is to do this without losing any updates. I know that in pure Java I would use synchronization but I'm not clear what the equivalent mechanism in the datastore is.

Upvotes: 4

Views: 1209

Answers (2)

Nick Johnson
Nick Johnson

Reputation: 101149

There's a number of ways to do this depending on your requirements, including sharding. Another option is described here.

Upvotes: 1

mchr
mchr

Reputation: 6251

I found this in another answer:

int retries = 0;
int NUM_RETRIES = 10;
while (true) // break out below                                                                                                                             
{
    retries++;
    pm.currentTransaction().begin();
    Object obj = pm.getObjectById(getTargetClass(), getKey());
    // Make update to obj                                                                                                                                   
    try
    {
        pm.currentTransaction().commit();
        break;
    }
    catch (JDOCanRetryException ex)
    {
        if (retries == NUM_RETRIES)
        {
            throw ex;
        }
    }
}

Apparently the commit call throws an exception if the entity being queried has been updated since the transaction started.

Upvotes: 0

Related Questions