Каков правильный способ атомарного увеличения счетчика в App Engine?

Я использую Java в Google App Engine и лучше всего знаком с интерфейсом хранилища данных JDO. Я пытаюсь реализовать простой счетчик загрузок, который хранит свои данные в хранилище данных App Engine.

Я ожидаю всего несколько тысяч загрузок в месяц, поэтому скорость обновления моего счетчика будет довольно низкой. Поэтому я пока не заинтересован в сегментировании счетчика.

Прагматически я, вероятно, мог бы игнорировать блокировку и смириться с тем, что иногда буду терять обновления. Однако я хотел бы знать, как правильно это сделать, не теряя обновлений. Я знаю, что в чистой Java я бы использовал синхронизацию, но мне не ясно, что такое эквивалентный механизм в хранилище данных.


person mchr    schedule 08.11.2011    source источник


Ответы (2)


Есть несколько способов сделать это в зависимости от ваших требований, включая сегментирование. Другой вариант описан здесь.

person Nick Johnson    schedule 09.11.2011

Я нашел это в другом ответе:

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;
        }
    }
}

По-видимому, вызов фиксации вызывает исключение, если запрашиваемый объект был обновлен с момента начала транзакции.

person mchr    schedule 09.11.2011
comment
Это просто стандартная транзакция, и она имеет стандартные проблемы с максимальной частотой обновления в хранилище данных. - person Nick Johnson; 09.11.2011