Sending JMS Messages over XA with WildFly – JBoss AS

This short tutorial shows how you can send JMS messages as part of an XA Transaction with JBoss AS / WildFly.

Messages running as part of an XA Transaction are coordinated by a Resource Manager along with other resources which are partecipating to the XA Transaction. In order to do that, you need to use a specific XA Connection Factory which is available under the JNDI name java:/JmsXA only.

@Resource(mappedName="java:/JmsXA")
ConnectionFactory connFactory;

This is a special JCA Connection factory which pools the Connection and ensures proper XA behavior.

Besides it, check the transaction attribute of the business method to be transacted to REQUIRED (which is the default) if you use container managed transactions (CMT). Or use the UserTransaction object when using bean managed transactions (BMT).

Here is an example of it:

@Stateless
public class JMSService {
 
    @Resource(mappedName = "java:jboss/jms/queue/exampleQueue")
    private Queue queueExample;
 
    @Resource(mappedName = "java:/JmsXA")
    private ConnectionFactory cf;
 
    private Connection connection;
    private MessageProducer publisher;
    private Session session;

    @TransactionAttribute(TransactionAttributeType.REQUIRED)
    public void sendMessage(String txt) {
 
        try {         
 
            connection = cf.createConnection();
            session = connection.createSession();
 
            publisher = session.createProducer(queueExample);
 
            connection.start();
 
            TextMessage message = session.createTextMessage(txt);
            publisher.send(message);
 
 
        }
        catch (Exception exc) {
            exc.printStackTrace();
        }
        finally {         
  
          if (publisher != null) try { publisher.close(); } catch (Exception ignore) { }
          if (session != null) try { session.close(); } catch (Exception ignore) { }
          if (connection != null) try { connection.close(); } catch (Exception ignore) { }
   
 
         }
    } 
}

In the above example, the JMS session will participate in the JTA transaction and will be committed or rolled back when that transaction is committed or rolled back, without calling the session’s commit or rollback methods. Since the transaction is driven by the Container, the JMS Session arguments (transacted and acknowledgeMode) are ignored so we can omit them.

Found the article helpful? if so please follow us on Socials