Question

J'ai un scénario très simple impliquant un base de données et JMS dans un serveur d'application (Glassfish). Le scénario est simple comme:

1. an EJB inserts a row in the database and sends a message.
2. when the message is delivered with an MDB, the row is read and updated. 

Le problème est que, parfois, le message est livré avant l'insertion a été commise dans la base de données. Ceci est en fait compréhensible si l'on considère le protocole de validation de phase 2:

1. prepare JMS
2. prepare database
3. commit JMS
4. ( tiny little gap where message can be delivered before insert has been committed)
5. commit database

J'ai discuté ce problème avec d'autres , mais la réponse a toujours été:. "Etrange, il devrait fonctionner hors de la boîte"

Mes questions sont alors:

  • Comment pourrait-il fonctionner hors de la boîte?
  • Mon scénario semble assez simple, pourquoi est-il pas plus de gens avec des problèmes similaires?
  • Est-ce que je fais quelque chose de mal? Y at-il un moyen de résoudre ce problème correctement?

Voici un peu plus de détails sur ma compréhension du problème:

Ce problème de synchronisation n'existent que si le participant sont traités dans cet ordre. Si le 2PC traite les participants dans l'ordre inverse (base de données d'abord, puis courtier de messages) qui devrait être bien. Le problème qui se passait au hasard, mais tout à fait reproductible.

J'ai trouvé aucun moyen de contrôler l'ordre des participants aux transactions distribuées dans les spécifications JTA, JCA et JPA ni dans la documentation Glassfish. On peut supposer qu'ils seront enrôlés dans la transaction distribuée selon l'ordre quand ils sont utilisés, mais avec un ORM tels que JPA, il est difficile de savoir quand les données sont vidées et lorsque la connexion de base de données est vraiment utilisé. Toute idée?

Était-ce utile?

La solution

Vous rencontrez le XA classique condition de course 2-PC. Il ne se produit dans des environnements de production.

Il y a 3 choses qui viennent à l'esprit.

  1. l'optimisation dernier agent où JDBC est la ressource non-XA. (Perdre la sémantique de récupération)
  2. Avez JMS Time-To-deliver. (Délibérément perdre du temps réel)
  3. Construire en code JDBC relances. (Effet moins sur la fonctionnalité)

Weblogic a cette optimisation de LLR évite ce problème et vous donne toutes les garanties XA.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top