J'essaie de porter l'exemple Sharding Counters (code.google.com/appengine/articles/sharding_counters.html) à Java. Le seul problème est que l'API Java n'a pas un appel similaire à 'get_by_key_name' de Python. Telle est l'idée de base:Comment déterminer si un objet existe pour une clé donnée dans le magasin de données Google AppEngine à l'aide de Java?
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();
Malheureusement, cela jette un JDOObjectNotFoundException la première fois que je le lance. Je pourrais lancer une requête pour déterminer si un compteur existe pour un nom donné, mais ce n'est pas transactionnel. Un autre thread pourrait faire la même chose et à la fin les deux créeraient un objet avec la même clé. D'après ce que je comprends, les seules opérations supportées dans une transaction (pour l'API Java) sont get et put. Alors, comment puis-je verrouiller un objet par une clé qui n'existe pas encore (c'est-à-dire ne pas 'obtenir') et m'assurer que je suis le premier et le seul à le créer?
Tu ne peux pas attraper juste le JDOObjectNotFoundException et de créer l'entité dans ce cas? –
Je pourrais le faire, mais ce n'est pas encore transactionnel. Au moment où je crée un nouveau fragment avec le compte "1", une autre requête pourrait entrer. Je regarderai dans les groupes d'entités et les clés parentes. Peut-être que c'est le chemin à parcourir. –
Il est transactionnel si vous le faites en une seule transaction. La transaction échouera (comme prévu) si l'entité que vous avez essayé d'obtenir a été insérée ou mise à jour avant que vous puissiez valider. C'est exactement comme cela que fonctionne le gety_insert du SDK Python. –