27 votes

Les écritures JDO validées ne s'appliquent pas au GAE HRD local, ou éventuellement à une transaction réutilisée

Je suis l'aide de JDO 2.3 sur app engine. J'ai été en utilisant le Maître/Esclave de la banque de données pour les tests locaux et récemment basculé à l'aide de la DRH de la banque de données pour les tests locaux, et des parties de l'une de mes applications sont de rupture (ce qui est à prévoir). Une partie de l'application, la rupture est l'endroit où il envoie beaucoup de écrit rapidement - c'est à cause de la 1-deuxième limite de chose, c'est de la faute de avec en même temps une modification de l'exception.

Ok, donc c'est également à prévoir, donc, j'ai le navigateur de nouvelle tentative de l'écrit à nouveau plus tard quand ils ne parviennent pas (peut-être pas le meilleur hack mais je suis juste en train de le faire rapidement).

Mais une chose étrange qui se passe. Certains de l'écrit qui doit être réussir (ceux qui NE sont PAS les modifications simultanées exception) sont également défaut, même si la phase de validation est terminée et que la requête retourne mon code de succès. Je peux le voir dans le journal que le retenté les demandes de travail sont d'accord, mais ces autres demandes qui semblent avoir commis sur le premier essai sont, je suppose, jamais "appliquées". Mais de ce que j'ai lu à propos de les Appliquer phase, écrit de nouveau à la même entité doit forcer l'appliquer... mais il ne le fait pas.

Le Code qui suit. Certaines choses sont à noter:

  1. Je suis d'essayer d'utiliser automatique JDO la mise en cache. C'est donc là que JDO utilise memcache sous les couvertures. Cela ne fait pas travailler à moins que vous enveloppez le tout dans une transaction.
  2. toutes les demandes sont à faire est de lire une chaîne de caractères de l'entité, la modification d'une partie de la chaîne, et la sauvegarde de cette chaîne à l'entité. Si ces demandes n'étaient pas dans les transactions, vous feriez bien sûr la "sale lire" problème. Mais avec des transactions, l'isolation est censé être au niveau de "serializable" donc je ne vois pas ce qui se passe ici.
  3. l'entité en cours de modification est une racine de l'entité (et non pas dans un groupe)
  4. J'ai de la croix-transactions du groupe activé

Le code (c'est une version simplifiée):

PersistenceManager pm = PMF.getManager();
Transaction tx = pm.currentTransaction();
String responsetext = "";
try {
    tx.begin();
    // I have extra calls to "makePersistent" because I found that relying
    // on pm.close didn't always write the objects to cache, maybe that
    // was only a DataNucleus 1.x issue though
    Key userkey = obtainUserKeyFromCookie();
    User u = pm.getObjectById(User.class, userkey);
    pm.makePersistent(u); // to make sure it gets cached for next time
    Key mapkey = obtainMapKeyFromQueryString();
    // this is NOT a java.util.Map, just FYI
    Map currentmap = pm.getObjectById(Map.class, mapkey);
    Text mapData = currentmap.getMapData(); // mapData is JSON stored in the entity
    Text newMapData = parseModifyAndReturn(mapData); // transform the map
    currentmap.setMapData(newMapData); // mutate the Map object
    pm.makePersistent(currentmap); // make sure to persist so there is a cache hit
    tx.commit();
    responsetext = "OK";
} catch (JDOCanRetryException jdoe) {
    // log jdoe
    responsetext = "RETRY";
} catch (Exception e) {
    // log e
    responsetext = "ERROR";
} finally {
    if (tx.isActive()) {
        tx.rollback();
    }
    pm.close();
}
resp.getWriter().println(responsetext);

Mise à JOUR: je suis assez sûr que je sais pourquoi ce qui se passe, mais je vais toujours de l'attribution de la prime à tous ceux qui peuvent le confirmer.

Fondamentalement, je pense que le problème est que les transactions ne sont pas vraiment mis en œuvre dans la version locale de la banque de données. Références:

https://groups.google.com/forum/?fromgroups=#!topic/google appengine-java/gVMS1dFSpcU https://groups.google.com/forum/?fromgroups=#!topic/google appengine-java/deGasFdIO-M https://groups.google.com/forum/?hl=en&fromgroups=#!msg/google-appengine-java/4YuNb6TVD6I/gSttMmHYwo0J

Parce que les transactions ne sont pas mises en œuvre, la restauration est essentiellement un no-op. Donc, je suis un sale lire lors de deux opérations d'essayer de modifier l'enregistrement en même temps. En d'autres termes, Un lit les données et B lit les données en même temps. Une tentative pour modifier les données, et B tente de modifier une partie différente des données. Un écrit à la banque de données, puis B écrit, oblitérer Un modifications. Alors B est "annulée" par app engine, mais depuis les restaurations sont un no-op lors de l'exécution sur le magasin de données local, les B des changements de séjour, et ne le font pas. En attendant, puisque B est le thread qui a déclenché l'exception, le client tentatives B, mais n'essaie pas de A (car a est soi-disant la transaction qui a réussi).

1voto

Zied Hamdi Points 877

Peut-être une mauvaise nouvelle pour vous, j'ai quitté JDO et je suis à l'aide d'Objectiver et à certains endroits directement datanucleus. J'ai un contrôle parfait de ma persévérance qui est une performance et de la conception de meilleurs choix (si vous pensez que dans le long terme).

Parce que la bd est no-sql, il y a des changements structurels à l'encontre de JPA, JDO et des hypothèses standard:

À l'aide de la maternelle datanucleus API, vous pouvez faire des choses qui ne sont pas dans la norme JPA, ni même à Objectiver : L'exemple que j'ai utilisé était de créer des colonnes dynamiquement

La transaction n'est pas présent en FGA, il y a quelque chose qui peut parfois ressembler à une transaction (groupes d'entité). Donc, en utilisant l'API native de vous éviter de faire de tels imprevisible de la gymnastique.

Essayer de conduire une voiture avec une manette de jeu pourrait fonctionner, mais il y a sûrement de nouvelles choses à apprendre. À mon avis c'est la peine d'apprendre le natif de façon

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X