Я пытаюсь перенести пример Sharding Counters (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) поддерживаются только операции получения и размещения. Итак, как я могу заблокировать объект с помощью еще не существующего ключа (т. е. без «получения») и убедиться, что я первый и единственный, кто его создает?