在App Engine中以原子方式增加计数器的正确方法是什么? [英] What is the correct way to atomically increment a counter in App Engine?
问题描述
我在Google App Engine上使用Java,并且我最熟悉JDO数据存储接口。我试图实现一个简单的下载计数器,将其数据存储在App Engine数据存储中。
我只需要每月下载数千次的下载量,因此我的计数器的更新率会非常低。因此,我对分解计数器并不感兴趣。
实际上,我可能会忽略锁定并接受偶尔会丢失更新。不过,我想知道在不丢失任何更新的情况下做到这一点的正确方法。我知道在纯Java中我会使用同步,但我不清楚数据存储区中的等价机制是什么。
我发现这在另一个答案: int retries = 0;
int NUM_RETRIES = 10;
while(true)// break out
{
retries ++;
pm.currentTransaction()。begin();
Object obj = pm.getObjectById(getTargetClass(),getKey());
//更新为obj
尝试
{
pm.currentTransaction()。commit();
休息;
catch(JDOCanRetryException ex)
{
if(retries == NUM_RETRIES)
{
throw ex;
}
}
}
显然,如果被查询的实体自交易开始以来已更新,则为异常。
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.
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.
这篇关于在App Engine中以原子方式增加计数器的正确方法是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!