1

J'ai seulement besoin de confirmation que je comprends bien. Si, par exemple, j'ai une entité X avec un champ x, et quand une demande est envoyée, je veux faire X.x++. Si j'utilise seulement X = ofy().load().type(X.class).id(xId).get() alors je fais quelques calculs et ensuite je fais X.x++ et je le sauvegarde. Si au cours des calculs une autre demande est affichée, j'obtiens un comportement indésirable. Et à la place, si je fais tout cela dans une transaction, la deuxième demande n'aura pas accès à X jusqu'à ce que je finisse.Objectify transaction vs charge régulière puis enregistrer

Est-ce vrai? Désolé, la question est un peu nooby.

Merci, Dan

Répondre

2

Oui vous l'avez raison, mais lorsque vous utilisez transaction rappelez-vous la première qui complète gagne et que les autres échouent. Regardez aussi la réponse de @Peter Knego pour savoir comment ils fonctionnent.

Mais ne vous inquiétez pas de la deuxième requête si elle ne parvient pas à lire. Vous avez comme 2 options:

  1. force retries
  2. Utiliser la cohérence éventuelle dans vos transactions

En ce qui concerne les relances sont concernés:

Votre fonction transaction peut être appelé plusieurs fois en toute sécurité sans effets secondaires indésirables. Si cela est impossible, vous pouvez définir retries = 0, mais sachez que la transaction échoue sur le premier l'incident de discorde

Exemple:

@db.transactional(retries=10) 

En ce qui cohérence à terme est concerné :

Vous pouvez désactiver cette protection en spécifiant une règle de lecture pour laquelle demande une cohérence éventuelle. Avec une lecture éventuellement cohérente de une entité, votre application obtient l'état connu actuel de l'entité en cours de lecture , indépendamment du fait que les modifications validées soient toujours appliquées. Avec une requête ancêtre éventuellement cohérente, les index utilisés pour la requête sont cohérents avec le moment où les index sont lus à partir du disque. En d'autres termes, une règle de lecture de cohérence éventuelle entraîne le comportement des requêtes et des requêtes comme si elles ne faisaient pas partie de la transaction en cours. Cela peut être plus rapide dans certains cas, car les opérations ne doivent pas attendre que les modifications validées soient écrites avant de renvoyer un résultat.

Exemple:

@db.transactional() 
def test(): 
    game_version = db.get(
     db.Key.from_path('GameVersion', 1), 
     read_policy=db.EVENTUAL_CONSISTENCY) 
2

Non, transaction GAE ne fait pas de verrouillage, ils utilisent optimistic concurrency control.Vous aurez accès à X tout le temps, mais lorsque vous essayez de l'enregistrer dans les secondes transactions, il échouera avec ConcurrentModificationException.

+0

OK, dans mon cas, quand je veux exécuter 'X.x ++', après avoir reçu une requête, je devrais le faire dans une transaction, dans le cas où deux requêtes arriveraient presque simultanément? – RCB

Questions connexes