2010-04-12 3 views
3

Nous avons un conteneur d'écoute de messages Spring JMS pour recevoir des messages de manière asynchrone. Utilisation de DefaultMessageListenerContainer et en mode sessionTransacted. Je comprends qu'être en sessionLe mode Transféré signifie qu'en cas d'exception, le message sera remis dans la file d'attente. Mais comment puis-je m'assurer que le message ne sera pas effacé de la file d'attente même si le récepteur (qui a choisi le message) se bloque ou que la machine qui l'utilise perd de la puissance?Conservation des messages dans la file d'attente en cas de panne du récepteur

Au début, je pensais que le mode d'accusé de réception CLIENT_ACKNOWLEDGE devrait me sauver, mais apparently ce n'est pas le cas, Spring appelle .acknowledge() quoi qu'il arrive.

Alors, voici ma question, comment puis-je garantir la livraison? En utilisant un MessageListenerContainer personnalisé? Utiliser un gestionnaire de transactions?

Répondre

1

Utilisez une session traitée et indiquez le succès du traitement du message en appelant la méthode de la classe commit().

Vérifiez la section 19.4.5. Processing messages within transactions pour la configuration. (vous pouvez utiliser un DefaultMessageListenerContainer). En fonction de ce que vous faites avec les messages, vous pouvez avoir besoin d'un gestionnaire de transactions JTA.

-1

ou vous pouvez utiliser la méthode Session.AUTO_ACKNOWLEDGE avec la session nontransacted, voir citation ci-dessous de cette article

Un message est automatiquement reconnu quand il avec succès les retours de la réception(). Si le récepteur utilise l'interface MessageListener , le message est automatiquement accusé de réception lorsqu'il renvoie avec succès de la méthode onMessage(). Si une erreur se produit lors de l'exécution de la méthode receive() ou de la méthode onMessage(), le message est automatiquement renvoyé. Le fournisseur JMS gère avec soin la remise de message et garantit une sémantique de livraison unique.

+0

-1 parce que la conclusion tirée de ce document est incorrecte. Oui, il y a redelivery si l'appel receive() ou onMessage() échoue mais cela ne signifie pas que le destinataire a eu une chance de faire quelque chose avec le message. Si le récepteur se bloque à ce moment, le message est irrémédiablement perdu, ce que OP essayait d'éviter.Toutefois, l'utilisation d'une session traitée et d'appels de validation explicites, comme décrit dans l'autre réponse, empêche une telle perte de messages si le récepteur tombe en panne. –

+0

Donc, en bref, l'article est trompeur? Quelle est la signification de l'accident? Si la méthode onMessage ne retourne pas en raison d'une panne, le message ne sera-t-il pas renvoyé? – soody

+0

Je ne dis pas que l'article est trompeur, mais qu'il ne s'applique pas à la question originale. Tous les échecs mentionnés dans la citation d'article se produisent avant que le message ne soit renvoyé à l'application. OP voulait retarder l'accusé de réception de message jusqu'à ce que le message ait été renvoyé et que l'application l'ait traité, comme CLIENT_ACKNOWLEDGE est censé fournir. La définition de Session.AUTO_ACKNOWLEDGE applique réellement le comportement que OP essayait d'empêcher. –

0

L'écouteur de message de printemps avec le mode Client_Acknowledge va accuser réception du message lorsque le client appelle message.acknowledge().

Cependant, si après l'exécution réussie du message, le consommateur ne trouve aucun accusé de réception du côté client, le ressort suppose que l'exécution a réussi et acquitte le message. Si à tout moment, le client a reçu une exception lors du traitement du message, l'écouteur de printemps doit savoir qu'une exception s'est produite afin de relancer le message dans la file d'attente pour qu'un autre thread consommateur le prenne en charge. Si vous attrapez l'exception, le printemps suppose que tout a été géré et que l'exécution s'est déroulée sans heurt, ce qui confirme le message.

L'écouteur de message de printemps permet uniquement de lancer une exception JMS à partir de l'écouteur onMessage. Attraper votre exception personnalisée et lancer une exception JMS à partir de l'écouteur (après avoir enregistré l'erreur pour référence future) vous permettra de relancer le message.

Questions connexes