JMS and Spring batch

5.1k Views Asked by At

Our project is to integrate two applications, using rest api of each, using JMS(to provide asynchronous nature) and spring batch to read bulk data from the JMS queue and process it and then post it to the receiving application.

I am a newbie to both JMS and spring batch. I have few basic questions to ask:

  • Which JMS model to ahead with-(PTP or Pub/Sub)
  • Can messages be read in bulk from the JMS queue(using JMSItemReader). If yes, can anyone pls provide with a code.
  • We want to acknowledge messages as 'read' once it is successfully posted (ie. read-process-write) to receiving application and not when it is read by the JMSItemReader. How can we achieve this?

The high level design diagram is below enter image description here

1

There are 1 best solutions below

0
On

PTP vs Pub/sub

The point to point method using a message queue is the most standard method to go. Especially in a batch application I can not see immediate reason to use Publish subscribe which presumes you have multiple consumers of the same messages.

Theoretically If multiple functions need to be executed over the same chunks of data you can organize the different processors as subscribers this way scaling the application, but this is pretty advanced usage scenario.

Can messages be read in bulk from JMS queue:

The JMS specification here only talks (vaguely might be misreading it) about bulk acknowledgment of messages, but it does not set a requirement over bulk delivery of messages.

CLIENT_ACKNOWLEDGE - With this option, a client acknowledges a message by calling the message’s acknowledge method. Acknowledging a consumed message automatically acknowledges the receipt of all messages that have been delivered by its session.

Simply put the answer with respect of the bulk delivery is "If the JMS provider supports it, then yes, otherwise no"

Most providers allow bulk acknowledgment of messages

Here is the Oracles' interface doing that:

public interface com.sun.messaging.jms.Message {
          void acknowledgeThisMessage() throws JMSException;
          void acknowledgeUpThroughThisMessage() throws JMSException;
}

A combination of CLIENT_ACKNOWLEDGE . + invoking the method acknowledgeUpThroughThisMessage on a . message will acknowledge all messages received up to that moment in time.

Manual acknowledgment of messages:

This can be achieved through CLIENT_ACKNOWLEDGE and the acknowledge method on the Message. Here I will quote you again the javadoc of the acknowledge method which is also referencing one more time your second question and it talks about bulk acknowledgment of all messages up to a point.

void acknowledge() throws JMSException Acknowledges all consumed messages of the session of this consumed message. All consumed JMS messages support the acknowledge method for use when a client has specified that its JMS session's consumed messages are to be explicitly acknowledged. By invoking acknowledge on a consumed message, a client acknowledges all messages consumed by the session that the message was delivered to.

Calls to acknowledge are ignored for both transacted sessions and sessions specified to use implicit acknowledgement modes.

A client may individually acknowledge each message as it is consumed, or it may choose to acknowledge messages as an application-defined group (which is done by calling acknowledge on the last received message of the group, thereby acknowledging all messages consumed by the session.)

Messages that have been received but not acknowledged may be redelivered.