Search code examples
javaejbjms

Transactionality while Sending JMS Response


I am currenlty involved in the development of a JMS Request Response service using EJB. The service receives JMS Messages as request through MDB and responds back with a JMS Message ( using the ReplyToQ configured in the request ).

The requirement is that even in case an error happens in the service, a response should be sent back. If the response is being sent within the onMessage() method, then it is being sent within the same transaction where the request is being processed or received. In this case, when an error happens the transaction gets rolled back and hence the response is not being sent.

So, i have moved the part of the code which sends the response, to a method, in a different stateless Session bean with TransactionAttribute.REQUIRES_NEW. The code works now..

But I am a bit confused as to whether to have the response send method in a new transaction using the TransactionAttribute.REQUIRES_NEW or have it as TransactionAttribute.NOT_SUPPORTED. Can you please let me know which is better..using TransactionAttribute.REQUIRES_NEW or using TransactionAttribute.NOT_SUPPORTED over the method.

I have provided an excerpt from the code below

   @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
       public void sendResponse(Message inMessage, Object responseObj)
        throws JMSException {
          Connection jmsConnection = null;
    Session jmsSession = null;
    try {

        jmsConnection = getConnection();
        Destination jmsDestination = inMessage.getJMSReplyTo();
        jmsSession = jmsConnection.createSession(false,
                Session.AUTO_ACKNOWLEDGE);
        String marshalTxt = "Sample Response";
        Message responseMessage = jmsSession.createTextMessage(marshalTxt);
        responseMessage.setJMSCorrelationID(getCorrelId());
        jmsSession.createProducer(jmsDestination).send(responseMessage);
    } catch (JMSException | IllegalStateException exception) {
        LOGGER.error("void sendResponse ->Unable to send the response",
                exception);
        throw exception;
    }finally{
        if(jmsConnection != null){
        jmsConnection.close();
        }
    }
}

Thanks in Advance.


Solution

  • The lightest weight is going to be NOT_SUPPORTED so there no transactional overhead, but assumes that response sending is always going to succeed and there's no need to rollback that transaction. If there are error conditions that might require yanking back the response and, I guess, sending a different response, then transactions might be necessary. However, I'd hope that all the processing is done before you send the response, and then commit/rollback the overriding transaction afterwards.