2010-06-05 2 views
1

J'essaie de connecter une application externe à un conteneur JBoss AS. L'application externe est une application Java qui est actuellement notifiée des modifications apportées aux entités de base de données via une rubrique JMS. J'ai ajouté une classe EntityLifecycleListener à toutes mes entités qui publient une copie sérialisée (et dépliée) de l'entité sur la rubrique JMS.avoir une application java externe en informés des modifications apportées Entity EJB dans JBoss AS

Le problème est que cette mise en œuvre ne tient pas compte des limites de transaction du conteneur JBoss. Par exemple, l'événement @PostUpdate peut être déclenché, générant le message JMS pour cette entité, mais la transaction peut être annulée, ce qui entraîne la notification de l'application externe d'une modification non valide et l'annulation de la synchronisation.

J'ai besoin de ma demande externe à n'avisé de commits avec succès à la base de données, mais je dois être en mesure de publier l'ensemble de Java POJO à l'application externe. Existe-t-il un moyen officiel de le faire?

+0

C'est bizarre, je m'attends à des interactions avec JMS partie d'une transaction globale. Je vais creuser c'est un peu plus loin ... –

+0

Je suis sûr que je suis en utilisant les callbacks du cycle de vie de l'entité de manière incorrecte dans ce que je les utilise pour conduire des données en dehors des limites transaction/conteneurs qui je crois est un no- non selon l'APP. Je me demande si je devrais plutôt enregistrer un écouteur avec le bean EJB Entity Cache déployé par JBoss et utiliser le callback @TransactionCompleted pour publier l'objet après avoir vérifié que la transaction a réussi. –

Répondre

1

La spécification de l'APP sont un peu vague sur la démarcation de la transaction et l'auditeur (§ 3.5.2):

Les callbacks PreUpdate et PostUpdate se produisent avant et après les opérations de mise à jour de base de données à données d'entité, respectivement.

J'ai eu une situation similaire, et jusqu'à présent je me souviens, le rappel @PostXxxx étaient parfois exécutés dans la transaction correcte ou aucune transaction du tout. Cela dépend si la mise à jour a été une chasse « intermédiaire » dans la transaction ou la chasse « dernier » avant la transaction est validée, dans ce cas, le rappel se après la transaction a été commise (ce qui est logique).

Je vous suggère d'essayer avec @PreXxxxx qui devrait toujours être dans la transaction. (Aussi, si je me souviens bien, le seul problème avec @PreXxxx était que l'entité ne peut pas encore être assignée PK, si elle est problématique dépend de votre cas d'utilisation.)

+0

En utilisant le @PreXxxx ne serais-je pas publier des données périmées, car il se produirait avant que l'entité est mise à jour? Si la transaction est annulée, n'aurais-je pas le même problème? C'est un cas spécifique que je vois: J'appelle une méthode Session Bean; le bean charge une entité à partir de la base de données, apporte des modifications et ensuite effectue un EntityManager.flush(). Cela provoque la synchronisation du contexte persistant qui déclenche les écouteurs de rappel. La ligne suivante dans le haricot jette une exception. Cela provoque la annulation de la transaction et la non-validation des données. Mais j'ai toujours publié mon message JMS. –

+0

@John Pas si vous utilisez des transactions distribuées. Le vidage synchronise les données et déclenche le rappel. Le message est envoyé mais appartient à la transaction * distributed *. Si le tx échoue plus tard, rien n'est commis (db + jms). – ewernli

Questions connexes