在App Engine中以原子方式增加计数器的正确方法是什么? [英] What is the correct way to atomically increment a counter in App Engine?

查看:93
本文介绍了在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆