Search code examples
jakarta-eejmsejbstateless-session-bean

JMS messages sent from JavaEE with container managed transactions not sent until container commits the transaction


I have a JavaEE application that initiates long running transactions using a REST API (the requests return 202 Accepted).

I am using JMS to send progress messages to clients that have initiated these processes. However, no messages are sent until the long running process terminates. I believe this is because JMS is waiting for a commit and (by default) the container won't issue one until the process ends.

The majority of EJBs are @Stateless including the long running process and the EJB sending the messages.

I "solved" this by adding @TransactionAttribute(REQUIRES_NEW) on the method that sends the JMS message. I tried adding REQUIRES_NEW to selected methods in the long running task code but that didn't seem to work.

I am concerned that the large number of commits will adversely affect performance. Is there a better way?


Solution

  • I would confirm that the extra commits actually adversely affect performance in a statistically significant way before making any other changes. Your concern may be misplaced. As the venerable Donald Knuth famously stated, "Premature optimization is the root of all evil."

    If you find that the performance overhead of the extra commits is too great you might try using @TransactionAttribute(NOT_SUPPORTED) on either the method which sends the JMS message or the method which calls the method which sends the JMS message.

    Keep in mind that long-running transactions are generally considered an anti-pattern so you may want to ditch them completely unless absolutely necessary for data integrity (which doesn't appear to be the case given that REST APIs are rarely, if ever, transactional).