Я пытаюсь перенести пример счетчиков Sharding (code.google.com/appengine/articles/sharding_counters.html) на Java. Единственная проблема заключается в том, что Java API не имеет вызова, аналогичного Python 'get_by_key_name'. Это основная идея:
Transaction tx = pm.currentTransaction();
Key key = KeyFactory.createKey(CounterShard.class.getSimpleName(), counter + randomIndex);
CounterShard shard = pm.getObjectById(CounterShard.class, key);
if (shard == null) { // API does not work this way...
shard = new CounterShard(key, counter);
}
shard.increment();
pm.makePersistent(shard);
tx.commit();
К сожалению, это вызывает исключение JDOObjectNotFoundException при первом запуске. Я мог бы выполнить запрос, чтобы определить, существует ли счетчик для данного имени, но это не транзакция. Другой поток может сделать то же самое, и в конце оба создадут объект с тем же ключом.
Насколько я понимаю, только операции, поддерживаемые внутри транзакции (для Java API), получают и помещают. Итак, как я могу заблокировать объект по ключу, который еще не существует (то есть, нет 'get') и убедиться, что я первый и единственный, кто его создал?