7
votes

Transaction XA / JTA: Message JMS arrive avant que les modifications de DB soient visibles

Le contexte est:

  • producteur (transaction JTA pt ) est à la fois d'envoyer un message à la file d'attente JMS et de la mise à jour de la DB;
  • consommateur (transaction JTA ct ) écoute dans la même file d'attente et lit DB lorsque le message est reçu;
  • Server d'application - Weblogic, DB - Oracle.

    J'ai observé, que parfois ct n'est pas (encore?) Capable de voir les modifications de DB de PT , événement si le message JMS correspondant est déjà reçu ( Pt est commis?).

    Il semble que JTA ne puisse pas garantir la cohérence de ce type (cela a également été confirmé dans la présentation de Jurgen Holler "choix de transaction pour la performance" ).

    Quel est le meilleur moyen d'éviter un tel problème (sauf évident - sans utiliser JTA)?

    Merci.


2 commentaires

Juste une autre idée: puisque Weblogic & Oracle est déjà utilisé ... Vous pouvez aussi bien ajouter une cohérence (un cache en mémoire distribué pour la base de données). Vous mettez à jour le cache en même temps que la base de données (cache d'écriture), le cache a donc la dernière valeur immédiatement disponible sur votre consommateur (ou au moins avec une diminution de la latence).


Je vais jeter un coup d'oeil, merci


3 Réponses :


1
votes

0 commentaires

4
votes

Il semble donc qu'il n'y ait pas de solution simple, élégante et sans échec pour cela. Dans notre cas, il a été décidé de s'appuyer sur un simple mécanisme de remontage (lancer une exception et de laisser le message JMS à être écoulé après une certaine quantité de temps).

également considéré:

  • Marquage de DB DataSource en tant que dernière optimisation des ressources (LRCO) de la dernière ressource (LRCO) doit contrôler partiellement l'ordre de commettre la transaction XA). Rejeté en raison de la dépendance aux internes du serveur d'applications (WL).

  • Réglage de la livraisonLAYAY au message JMS, il ne peut donc être consommé qu'après un certain temps, lorsque la synchronisation (supposée) DB est terminée. Rejeté en raison du manque de garantie et de l'ajuster pour l'ajuster pour différents environnements.

    Publication du blog mentionné dans une autre réponse contient en effet toutes ces options et plusieurs autres options couvertes (mais pas définitive).


1 commentaires

Je suppose que la meilleure solution consisterait à permettre à la fois à la fois mécanisme de la rédelivière et à un petit retard de livraison afin que le besoin de rédelivières ne se produise que dans des cas extrêmes.



0
votes

Concernant la réponse:

"Il semble donc qu'il n'y a pas de solution simple, élégante et sans échec pour cette. Dans notre cas, il a été décidé de compter sur une nouvelle livraison Mécanisme (projetant une exception et laissant le message JMS à être Redeliverned après une certaine quantité de temps). "

Il ne s'agit que de la preuve de panne Si votre deuxième transaction qui commence après la transaction1 Les extrémités logiquement ont un moyen de détecter que les modifications de transaction 1 ne sont pas encore visibles et ne se sont pas encore visibles et explosent sur une exception TechICHAL.

Lorsque vous avez une transaction 2, c'est un processus différent de la transaction 1, cela est susceptible d'être possible de vérifier. Très probablement, la production de transaction 1 est nécessaire au succès de la transaction 2 pour aller de l'avant. Vous ne pouvez faire que des frites françaises que si vous avez des pommes de terre ... si vous n'avez pas de pommes de terre, vous pouvez exploser et essayer à nouveau la prochaine fois.

Toutefois, si votre processus qui se casse en raison de la DB apparaissant Staillet est le même processus qui fonctionne sur la transaction 1 elle-même. Vous venez d'ajouter des pommes de terre dans un intestin (par exemple une table de base de données) et de ne pas détecter que vous êtes intestin sur le dessus et continuez à exécuter des transactions sur PumpTit ... Un tel chèque peut être hors de vos mains.

Quelque chose du genre, arrive à être mon cas.

Une solution théorique pour cela pourrait très bien vouloir essayer d'induire une lecture sale sur la base de données en créant une entité artificielle équivalente au champ @version de JPA, forçant chaque processus qui doit fonctionner en série pour marteler une mise à jour sur un entité commune. Si la transaction 2 et 1 met à jour un champ commun sur une entité commune, le processus devra se briser - vous obtenez une exception de verroue optimiste JPA sur la deuxième transaction ou si vous obtenez une exception de mise à jour de lecture sale à partir de la DB.

Je n'ai pas encore testé cette approche, mais cela va probablement être le travail nécessaire, assez malheureusement.


1 commentaires

J'ai testé l'approche de l'écriture de lecture la même entité qui obligeait la lecture et l'écriture atteindre le DATBase et corrige le problème. Nous pouvons être assurés de la sérialisation logique de la logique commerciale avec cette approche.