问题
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.
回答1:
There's a number of ways to do this depending on your requirements, including sharding. Another option is described here.
回答2:
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.
来源:https://stackoverflow.com/questions/8058512/what-is-the-correct-way-to-atomically-increment-a-counter-in-app-engine