I have a problem with JMS and transactions that I do not quite understand. My application has one JDBC resource and two JMS queues. Message producers for queues are created in a single session without a bean from the same jms session object. I use the queues as follows: A entitiy is created and its identifier is stored as a property in the JMS message and sent to the queue. Creation of an object and presentation in a queue occur in one transaction. My message is managed by a bean and then it returns an object from the database through the identifier in the JMS message and processes it.
The code looks something like this:
public long doSomething(String message) { SomeObject obj = new SomeObject(message); entityManager.persist(obj) // submit to JMS queue try { Message jmsMessage = session.createMessage(); jmsMessage.setLongProperty("id", obj.getId()); messageProducer.send(jmsMessage); } catch (JMSException ex) { Logger.getLogger(NotificationQueue.class.getName()).log(Level.SEVERE, null, ex); } return obj.getId(); }
MDB onMessage method:
public void onMessage(Message message) { Long id; try { id = message.getLongProperty("id"); } catch (Exception ex) { Logger.getLogger(AlertMessageListener.class.getName()).log(Level.SEVERE, null, ex); throw new EJBException(ex); } SomeObject obj = entityManager.find(SomeObject.class, id); obj.process(); }
When an object is retrieved from the database in the onMessage () method, the following exception is present in the log file:
FINE: ENTRY com.test.app.alert.control.AlertMessageListener onMessage FINE: ENTRY com.test.app.alert.control.MessageDao find FINER: client acquired: 2104888816 FINER: TX binding to tx mgr, status=STATUS_ACTIVE FINER: acquire unit of work: 1368213481 FINEST: Execute query ReadObjectQuery(name="readObject" referenceClass=Message sql="SELECT ID, DTYPE, MESSAGE, REPORTTIME, SENDER_USERNAME, ALERTSTATE, TIMERHANDLE, CATEGORY_ID, PRIORITY_PRIOLEVEL FROM MESSAGE WHERE (ID = ?)") SEVERE: prepareTransaction (XA) on JMSService:jmsdirect failed for connectionId:7979865462417759232 due to Unknown JMSService server error ERROR: com.sun.messaging.jmq.jmsserver.util.BrokerException: Bad transaction state transition. Cannot perform operation PREPARE_TRANSACTION(56) (XAFlag=null) on a transaction in state STARTED(1). WARNING: JTS5031: Exception [java.lang.RuntimeException: javax.transaction.xa.XAException] on Resource [prepare] operation. SEVERE: rollbackTransaction (XA) on JMSService:jmsdirect failed for connectionId:7979865462417759232:transactionId=7979865462479908608 due to Unknown JMSService server error ERROR: com.sun.messaging.jmq.jmsserver.util.BrokerException: Bad transaction state transition. Cannot perform operation ROLLBACK_TRANSACTION(48) (XAFlag=null) on a transaction in state STARTED(1). WARNING: JTS5068: Unexpected error occurred in rollback javax.transaction.xa.XAException at com.sun.messaging.jms.ra.DirectXAResource.rollback(DirectXAResource.java:703) at com.sun.jts.jta.TransactionState.rollback(TransactionState.java:193) at com.sun.jts.jtsxa.OTSResourceImpl.rollback(OTSResourceImpl.java:333) at com.sun.jts.CosTransactions.RegisteredResources.distributeRollback(RegisteredResources.java:1063) at com.sun.jts.CosTransactions.TopCoordinator.rollback(TopCoordinator.java:2299) at com.sun.jts.CosTransactions.CoordinatorTerm.commit(CoordinatorTerm.java:420) at com.sun.jts.CosTransactions.TerminatorImpl.commit(TerminatorImpl.java:250) at com.sun.jts.CosTransactions.CurrentImpl.commit(CurrentImpl.java:623) at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:319) at com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate.commitDistributedTransaction(JavaEETransactionManagerJTSDelegate.java:173) at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:873) at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5115) at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4880) at com.sun.ejb.containers.MessageBeanContainer.afterMessageDeliveryInternal(MessageBeanContainer.java:1207) at com.sun.ejb.containers.MessageBeanContainer.afterMessageDelivery(MessageBeanContainer.java:1180) at com.sun.ejb.containers.MessageBeanListenerImpl.afterMessageDelivery(MessageBeanListenerImpl.java:86) at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:143) at $Proxy260.afterDelivery(Unknown Source) at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:328) at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:114) at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:496) at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:537) Caused by: com.sun.messaging.jmq.jmsservice.JMSServiceException: rollbackTransaction: rollback transaction failed. Connection ID: 7979865462417759232, Transaction ID: 7979865462479908608, XID: null at com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.rollbackTransaction(IMQDirectService.java:1827) at com.sun.messaging.jms.ra.DirectXAResource.rollback(DirectXAResource.java:672) ... 21 more Caused by: com.sun.messaging.jmq.jmsserver.util.BrokerException: Bad transaction state transition. Cannot perform operation ROLLBACK_TRANSACTION(48) (XAFlag=null) on a transaction in state STARTED(1). at com.sun.messaging.jmq.jmsserver.data.TransactionState.nextState(TransactionState.java:449) at com.sun.messaging.jmq.jmsserver.data.handlers.TransactionHandler.preRollback(TransactionHandler.java:1586) at com.sun.messaging.jmq.jmsserver.data.protocol.ProtocolImpl.rollbackTransaction(ProtocolImpl.java:777) at com.sun.messaging.jmq.jmsserver.service.imq.IMQDirectService.rollbackTransaction(IMQDirectService.java:1816) ... 22 more FINER: TX afterCompletion callback, status=ROLLEDBACK FINER: release unit of work FINER: client released FINEST: Register the existing object com.test.app.alert.entity.AlertMessage@7981d22 FINER: end unit of work commit FINEST: Register the existing object Mailserver FINEST: Register the existing object Low FINEST: Register the existing object u0 u0 (u0) FINEST: Register the existing object Sankt Augustin FINE: RETURN com.test.app.alert.control.MessageDao find ... WARNING: javax.ejb.EJBException javax.ejb.EJBException: Transaction aborted at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5121) at com.sun.ejb.containers.BaseContainer.postInvokeTx(BaseContainer.java:4880) at com.sun.ejb.containers.MessageBeanContainer.afterMessageDeliveryInternal(MessageBeanContainer.java:1207) at com.sun.ejb.containers.MessageBeanContainer.afterMessageDelivery(MessageBeanContainer.java:1180) at com.sun.ejb.containers.MessageBeanListenerImpl.afterMessageDelivery(MessageBeanListenerImpl.java:86) at com.sun.enterprise.connectors.inbound.MessageEndpointInvocationHandler.invoke(MessageEndpointInvocationHandler.java:143) at $Proxy260.afterDelivery(Unknown Source) at com.sun.messaging.jms.ra.OnMessageRunner.run(OnMessageRunner.java:328) at com.sun.enterprise.connectors.work.OneWork.doWork(OneWork.java:114) at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:496) at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:537) Caused by: javax.transaction.RollbackException at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:321) at com.sun.enterprise.transaction.jts.JavaEETransactionManagerJTSDelegate.commitDistributedTransaction(JavaEETransactionManagerJTSDelegate.java:173) at com.sun.enterprise.transaction.JavaEETransactionManagerSimplified.commit(JavaEETransactionManagerSimplified.java:873) at com.sun.ejb.containers.BaseContainer.completeNewTx(BaseContainer.java:5115) ... 10 more
The following INFO was in the log file a little earlier (after creating the object):
INFO: DXAR:start():Warning:Received diff Xid for open txnId:switching transactionId: DXAR Xid=(GlobalTransactionID=[ B@4eec2030 , BranchQualifier=[ B@703557ca ) DXAR TXid=7979865462479908608 got Xid=(GlobalTransactionID=[ B@3e16c853 , BranchQualifier=[ B@49b9e0fd ) got TXid=7979865462480472064
What exactly does this exception mean:
Bad transaction state transition. Cannot perform operation ROLLBACK_TRANSACTION(48) (XAFlag=null) on a transaction in state STARTED(1).
I am using Glassfish v3.1-b35 with JPA 2.0 (and Apache Derby) and the standard JMS provider that comes with GF. Transaction parameters - by default, as well as JMS resources (EMBEDDED mode). Transactions are managed by containers. Any ideas what is going wrong here? An exception happens quite often.