0

I am setting up JMS using ActiveMq in spring boot application. But unable to understand how to prevent sender (Message provider) to adding duplicate messages to queue.

My application initial JMS and message converter beans configuration as follows

@Bean
    public Queue queue() {
        return new ActiveMQQueue("pendingDocuments.queue");
    }


@Bean 
 public MessageConverter jacksonJmsMessageConverter() {
       MappingJackson2MessageConverter converter = new MappingJackson2MessageConverter();
            converter.setTargetType(MessageType.TEXT);
            converter.setTypeIdPropertyName("_type");
            return converter;
        }

Sender method implementation

@Autowired
private JmsMessagingTemplate jmsMessagingTemplate;

@Autowired
private Queue pendingDocumentsQueue;

public void getPendingDocuments(){

/*My Custom Java Object, Actually these objects will read from DB for every 5 min, so process no way to know either these are already added to queue or not*/

Document document= new Document();
document.setUniqueId("122212");
document.setContent("TEST CONTENT");
this.jmsMessagingTemplate.convertAndSend(this.pendingDocumentsQueue, document);

        }

I would like to know how can we add messages (my document object) to queue based on document unique id.

krish131
  • 163
  • 3
  • 14
  • 1
    *identifying* duplicate message is activemq's job, you don't have to code it your self, see [https://activemq.apache.org/components/artemis/documentation/1.0.0/duplicate-detection.html] , on the other hand if you want to avoid it - https://stackoverflow.com/questions/4934386/avoiding-duplicated-messages-on-jms-activemq – Milan Desai May 14 '19 at 10:17
  • I have gone through the links, but I am unable to understand where should I place following code in my configuration. message.setStringProperty(HDR_DUPLICATE_DETECTION_ID.toString(), myUniqueID); – krish131 May 14 '19 at 10:23
  • 1
    Possible duplicate of [Avoiding duplicated messages on JMS/ActiveMQ](https://stackoverflow.com/questions/4934386/avoiding-duplicated-messages-on-jms-activemq) – Justin Bertram May 14 '19 at 13:58
  • For what it's worth, the question appears to be about ActiveMQ 5.x and the documentation about setting the HDR_DUPLICATE_DETECTION_ID string property is for ActiveMQ Artemis (i.e. the next-generation ActiveMQ broker). – Justin Bertram May 14 '19 at 13:59

1 Answers1

0

If I understand this correctly you are trying to prevent your communication from processing duplicate messages even in the case of crashes ?

Normally, you shouldn't have duplicates (ActiveMQ doesn't create those 'on it's own'), but if you think about the possible points of failure (Sender crash, Broker crash, Consumer crash) you'll see that a Sender and a Broker can't make the decision of 'duplicate' unless the consumer told them about the last message actually processed.

This could happen by an internal ACK from consumer to broker (prevents missing messages but not duplicates) or by using JMS transactions which can also prevent from duplicates. If you make your sender and consumer use transacted sessions with jmsTemplate.setSessionTransacted(true); (see here) you will have a duplicate free communication with a protocol like this:

  1. Sender checks from a persistent store (could be a DB) what the next UniqueID is.
  2. Sender sends message.
  3. Sender commits transaction and at the same time makes a note of processing this UniqueID.
  4. The Broker will deliver this message with a unique transaction ID.
  5. Consumer receives the message.
  6. Consumer processes this UniqueID and at the same time commits the transaction.
Axel Podehl
  • 4,034
  • 29
  • 41
  • " If you make your sender and consumer use transacted sessions with jmsTemplate.setSessionTransacted(true); (see here) you will have a duplicate free communication..." - this is not true. In some circustances (especialy with failover) you can end up with duplicated messages. [Here's why](https://docs.spring.io/spring-framework/docs/5.2.8.RELEASE/spring-framework-reference/integration.html#jms-tx-participation). You need XA transaction manager to avoid this issue but in many modern architectures 2PC is not an option so you still need some kind of duplicates detection or idempotent consumer. – kemot90 Jun 17 '21 at 09:16