Environment: Win32 Environment Websphere 6.1.0.13 ActiveMQ 5.3.0 [Win32, same machine as WAS] ActiveMQ configured with accompanying Resource Adapter on Websphere.
Spring 2.5.6. Hibernate 3.3.2 LS, In preparation for our Websphere - Websphere MQ connection and absense of the latter on our dev boxes we decided to set up a test environment locally using Active MQ. It has served us well in a better understanding of jms/mq and messaging and configuring Spring to read out queues and setting up transactions. After the low hanging fruit, a bit more sophisticated use case came up: On the failure of parsing and storing a message, a new entry should be made in a a notification table, apart of course from dequeueing the message. The addNotification method in our NotificationService is wired with a REQUIRES_NEW transaction in an aop configuration, but the addNotification method fails with following exception: [18-3-10 9:35:38:230 CET] 00000022 XATransaction E J2CA0027E: An exception occurred while invoking end on an XA Resource Adapter from dataSource jms/gridMQFactory, within transaction ID {XidImpl: formatId(57415344), gtrid_length(36), bqual_length(54), data(000001277069dc4700000003000000b13663870e08a69927dc8e87578289a39c2b540745000001277069dc4700000003000000b13663870e08a69927dc8e87578289a39c2b540745000000010000000000000000000000000001)}: javax.transaction.xa.XAException at org.apache.activemq.ra.LocalAndXATransaction.end(LocalAndXATransaction.java:95) at com.ibm.ejs.j2c.XATransactionWrapper.end(XATransactionWrapper.java:574) at com.ibm.ws.Transaction.JTA.JTAResourceBase.end(JTAResourceBase.java:237) at com.ibm.ws.Transaction.JTA.RegisteredResources.sendEnd(RegisteredResources.java:1341) at com.ibm.ws.Transaction.JTA.RegisteredResources.distributeEnd(RegisteredResources.java:1315) at com.ibm.ws.Transaction.JTA.TransactionImpl.distributeEnd(TransactionImpl.java:2432) at com.ibm.ws.Transaction.JTA.TransactionImpl.prepareResources(TransactionImpl.java:2058) at com.ibm.ws.Transaction.JTA.TransactionImpl.stage1CommitProcessing(TransactionImpl.java:1646) at com.ibm.ws.Transaction.JTA.TransactionImpl.processCommit(TransactionImpl.java:1602) at com.ibm.ws.Transaction.JTA.TransactionImpl.commit(TransactionImpl.java:1537) at com.ibm.ws.Transaction.JTA.TranManagerImpl.commit(TranManagerImpl.java:239) at com.ibm.ws.Transaction.JTA.TranManagerSet.commit(TranManagerSet.java:163) at com.ibm.ws.uow.UOWManagerImpl.uowCommit(UOWManagerImpl.java:1055) at com.ibm.ws.uow.UOWManagerImpl.uowEnd(UOWManagerImpl.java:1025) at com.ibm.ws.uow.UOWManagerImpl.runUnderNewUOW(UOWManagerImpl.java:975) at com.ibm.ws.uow.UOWManagerImpl.runUnderUOW(UOWManagerImpl.java:509) at org.springframework.transaction.jta.WebSphereUowTransactionManager.execute(WebSphereUowTransactionManager.java:252) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:123) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:89) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:171) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204) at $Proxy1.addNotification(Unknown Source) <zip> Caused by: javax.jms.JMSException: The resource is allready being used in transaction context. at org.apache.activemq.ra.ManagedTransactionContext.setUseSharedTxContext(ManagedTransactionContext.java:47) at org.apache.activemq.ra.ManagedSessionProxy.setUseSharedTxContext(ManagedSessionProxy.java:67) at org.apache.activemq.ra.ManagedConnectionProxy.setUseSharedTxContext(ManagedConnectionProxy.java:138) at org.apache.activemq.ra.ActiveMQManagedConnection$1.setInManagedTx(ActiveMQManagedConnection.java:83) at org.apache.activemq.ra.LocalAndXATransaction.end(LocalAndXATransaction.java:93) ... 60 more We are suspecting the resource adapter for this as the exception occurs in "org.apache.activemq.ra.ManagedTransactionContext" and it works as expected on Websphere MQ. Below the layout of our spring jms configuration complete with relevant java code. If needed we can supply a minimal testcase to demonstrate the above documented behaviour. <bean id="gridMessageListener" class="nl.our.company.jms.GridMessageListener"> <property name="gridDAO" ref="gridDAO"/> <property name="processTypeDAO" ref="processTypeDAO"/> <property name="officeDAO" ref="officeDAO"/> <property name="notificationService" ref="notificationService"/> </bean> <jms:listener-container transaction-manager="txManager" task-executor="jmsTaskExecutor" connection-factory="trissJMSConnectionFactory" destination-resolver="destinationResolver"> <jms:listener destination="jms/gridQueue" ref="gridMessageListener" method="receive"/> </jms:listener-container> <bean id="destinationResolver" class="org.springframework.jms.support.destination.JndiDestinationResolver"> <property name="fallbackToDynamicDestination" value="true"/> <property name="resourceRef" value="true"/> </bean> The grid MessageListener's code: public void onMessage(Message msg) { String msgText = null; try { logger.trace("MSG IS " + msg + " messagetype is " + msg.getJMSType()); boolean success = false; if (msg instanceof TextMessage) { StreamSource source = new StreamSource(new ByteArrayInputStream( ((TextMessage) msg).getText().getBytes())); success = process(source); if (!success) { msgText = ((TextMessage) msg).getText(); } } else if (msg instanceof BytesMessage) { success = ... } else { logger.info("message is not recognized"); } } catch (JMSException e1) { logger.error("error occured: ", e1); } finally { if (msgText != null) { try { ProcessInfor pio = new ProcessInfo(..); notificationService.addNotification(NotificationTypeDAO.NOTIFICATION_TYPE_GRID_DELIVERY_FAILED , "GRID MQ Delivery Failed", msgText, pio, NotificationDAO.NOTIFICATION_SEVERITY_ERROR); } catch (Exception e) { logger.error("error ", e); } } } } The magic is happening in the process(source), which parses and stores the message. Unfortunately the parsing fails with a oracle "not null" exception. java.sql.BatchUpdateException: ORA-01400: <zip> at oracle.jdbc.driver.DatabaseError.throwBatchUpdateException(DatabaseError.java:343) [11-3-10 11:57:51:170 CET] 0000007f SystemOut O ERROR 11-03-10 11:57:51,092 nager : 10 nl.our.company.businesslayer.jms.GridMessageListener - error occured org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:636) Which we can and should solve on our side but, still we should be prepared for errors like this. The process method catches this exception, and returns false. Default our dao's and services are aop:advice'd with propagation:required, however the notificationService has a propegation:requires_new (we need the notificationService more than once outside current transactions) <tx:advice id="jmsAdvice" transaction-manager="txManager"> <tx:attributes> <!-- fix me change requires_new to required with xaexception --> <tx:method name="*" /> </tx:attributes> </tx:advice> <aop:pointcut id="jmsOperation" expression="execution(* nl.our.company.businesslayer.jms.GridMessageListener.onMessage(..))"/> <tx:advice id="newTxAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" propagation="REQUIRES_NEW" read-only="true"/> <tx:method name="*" propagation="REQUIRES_NEW"/> </tx:attributes> </tx:advice> <aop:advisor pointcut-ref="jmsOperation" advice-ref="jmsAdvice"/> <aop:pointcut id="newServiceOperation" expression="execution(* nl.ing.cmrm.aiss.businesslayer.services.ExportHistoryService.*(..)) or execution(* nl.ing.cmrm.aiss.businesslayer.services.NotificationService.*(..)) or execution(* nl.ing.cmrm.aiss.businesslayer.services.ProcessInfoService.*(..)) or execution(* nl.ing.cmrm.aiss.businesslayer.services.ImporterService.importDelivery(..)) or execution(* nl.ing.cmrm.aiss.businesslayer.services.ExporterService.insertExportHistory(..))"/> <aop:advisor pointcut-ref="newServiceOperation" advice-ref="newTxAdvice"/> -- View this message in context: http://old.nabble.com/ActiveMQ-on-Websphere-REQUIRES_NEW-transactions.-tp27943359p27943359.html Sent from the ActiveMQ - User mailing list archive at Nabble.com.