Search code examples
javatransactionswildflyactivemq-classic

Connection could not be created: javax.resource.ResourceException: IJ000460: Error checking for a transaction


We are getting the following exception while getting an ActiveMQConnection in our MDBClient class:

[org.apache.activemq.ra.ActiveMQConnectionFactory:100] (default-threads - 8) Connection could not be created:: javax.resource.ResourceException: IJ000460: Error checking for a transaction
    at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.getManagedConnection(TxConnectionManagerImpl.java:435)
    at org.jboss.jca.core.connectionmanager.AbstractConnectionManager.allocateConnection(AbstractConnectionManager.java:789)
    at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:94)
    at org.apache.activemq.ra.ActiveMQConnectionFactory.createConnection(ActiveMQConnectionFactory.java:67)
  Caused by: javax.resource.ResourceException: IJ000459: Transaction is not active: tx=Local transaction (delegate=TransactionImple < ac, BasicAction: 0:ffff0a91021d:6d03d951:608a090d:2d5 status: ActionStatus.ABORTED >, owner=Local transaction context for provider JBoss JTA transaction provider)
    at org.jboss.jca.core.connectionmanager.tx.TxConnectionManagerImpl.getManagedConnection(TxConnectionManagerImpl.java:419)

The code for getting connection is below. Error is happening on connectionFactory.createConnection(); One transaction is successful but all the subsequent transactions are failing with this error.

Our application is running on WildFly 21 and ActiveMQ 5.12.1. ActiveMQ is connected to WildFly through the ActiveMQ JCA Resource Adapter

ConnectionFactory connectionFactory = serviceLocator.getConnectionFactory("java:/ActiveMQ/QueueConnectionFactory");
Connection connection = connectionFactory.createConnection();
Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
Destination destination = serviceLocator.getDestination(conf.getProperty(SystemConfig.OUTPUT_QUEUE_JNDI_NAME));
MessageProducer messageProducer = session.createProducer(destination);

Any help is much appreciated.


Solution

  • By default when an MDB receives a message the Java EE container automatically starts a transaction which includes the consumption of the message and any other transactional work which the MDB performs (e.g. database updates, sending other JMS messages, etc.). In this way the JMS message is like a unit of work and the consumption of the message along with any other transactional work is performed atomically. If any part of the work fails then every part is rolled-back and, depending on the configuration, the message is either placed back onto the queue (for the MDB to attempt to consume it again) or send to a dead-letter queue or perhaps even discarded.

    When you get a connection from a JCA-based connection factory the JCA subsystem tries to automatically enlist that resource into any ongoing transaction. In this case the transaction is not active possibly due to a timeout or some other kind of previous failure. You should look through your logs to see if there were any failures prior to this that would shed any light on why the transaction as been aborted.

    The default transaction timeout is 300 seconds (i.e. 5 minutes) so if your transaction lasts longer than this you'll see this kind of error. Long-running transactions are an anti-pattern so you should take measures to avoid them if at all possible. If you absolutely must increase the transaction timeout then this article has a good explanation of how to do that.