I'm using JMS with GlassFish application server v2, and Spring 2.5.5. I want to read JMS messages with concurrent consumers, so I use the DefaultMessageListenerContainer, but I have some errors on the console (althougn the consumption of messages works fine):
Code:endTransaction (XA) on JMSService:jmsdirect failed for connectionId:6762471324442619392 and flags=67108864 due to unkown JMSService server error. RAR5031 : Exception système. javax.transaction.SystemException at com.sun.jts.jta.TransactionImpl.delistResource(TransactionImpl.java:250) at com.sun.enterprise.distributedtx.J2EETransaction.delistResource(J2EETransaction.java:548) at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.delistResource(J2EETransactionManagerImpl.java:833) at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.delistResource(J2EETransactionManagerOpt.java:229) at com.sun.enterprise.resource.ResourceManagerImpl.unregisterResource(ResourceManagerImpl.java:265) at com.sun.enterprise.resource.ResourceManagerImpl.delistResource(ResourceManagerImpl.java:223) at com.sun.enterprise.resource.PoolManagerImpl.resourceClosed(PoolManagerImpl.java:400) at com.sun.enterprise.resource.ConnectorAllocator$ConnectionListenerImpl.connectionClosed(ConnectorAllocator.java:72) at com.sun.messaging.jms.ra.ConnectionEventListener.sendEvent(ConnectionEventListener.java:143) at com.sun.messaging.jms.ra.ManagedConnection.sendEvent(ManagedConnection.java:675) at com.sun.messaging.jms.ra.DirectConnection.close(DirectConnection.java:231) at org.springframework.jms.connection.ConnectionFactoryUtils.releaseConnection(ConnectionFactoryUtils.java:81) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:357) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:240) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:944) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:868) at java.lang.Thread.run(Thread.java:619)
I found a workaround to remove these errors: I set the transactionSynchronizationName property of the jtaTransactionManager to SYNCHRONIZATION_NEVER, and I modified the AbstractPollingMessageListenerContainer to commit the transaction before the call of ConnectionFactoryUtils.releaseConnection (I removed the transactionManager.commit statement from the receiveAndExecute method, and I put it before the 2 return statements of the method doReceiveAndExecute).
But I hope there is a better solution, I wonder if I misconfigured something.
I have an other problem: on my MessageListener, I rollback the transaction by using transactionManager.rollback(transaction); but if I use transaction.setRollbackOnly(); the transaction is not rollbacked. I want to use this method to avoid these errors:
Here is my configuration:Code:[jmsContainer-3] ERROR DefaultMessageListenerContainer - Listener exception overridden by rollback exception org.springframework.transaction.UnexpectedRollbackException: JTA transaction unexpectedly rolled back (maybe due to a timeout); nested exception is javax.transaction.RollbackException at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1031) at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:709) at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:678) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:330) at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:227) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:932) at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:856) at java.lang.Thread.run(Thread.java:619) Caused by: javax.transaction.RollbackException at com.sun.jts.jta.TransactionManagerImpl.commit(TransactionManagerImpl.java:311) at com.sun.enterprise.distributedtx.J2EETransactionManagerImpl.commit(J2EETransactionManagerImpl.java:1030) at com.sun.enterprise.distributedtx.J2EETransactionManagerOpt.commit(J2EETransactionManagerOpt.java:397) at com.sun.enterprise.distributedtx.UserTransactionImpl.commit(UserTransactionImpl.java:197) at org.springframework.transaction.jta.JtaTransactionManager.doCommit(JtaTransactionManager.java:1028) ... 7 more
and my MessageListener:HTML Code:<?xml version="1.0" encoding="UTF-8"?> <beans> <!--ConnectionFactory and queue.--> <bean id="jmsQueueConnectionFactory" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate"/> </property> <property name="jndiName"> <value>jms/myQueueConnectionFactory</value> </property> </bean> <bean id="queue" class="org.springframework.jndi.JndiObjectFactoryBean"> <property name="jndiTemplate"> <ref bean="jndiTemplate"/> </property> <property name="jndiName"> <value>myQueue</value> </property> </bean> <bean id="jndiTemplate" class="org.springframework.jndi.JndiTemplate"/> <!--Listener--> <bean id="messageListener" class="testjmsreceiver.MessageListenerConsumer"> <constructor-arg> <ref bean="jtaTransactionManager"/> </constructor-arg> </bean> <bean id="jmsContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer"> <property name="connectionFactory" ref="jmsQueueConnectionFactory"/> <property name="destination" ref="queue"/> <property name="messageListener" ref="messageListener" /> <property name="concurrentConsumers" value="2" /> <property name="maxConcurrentConsumers" value="2" /> <property name="transactionManager" ref="jtaTransactionManager" /> </bean> <bean id="jtaTransactionManager" class="org.springframework.transaction.jta.JtaTransactionManager"> <property name="transactionSynchronizationName" value="SYNCHRONIZATION_NEVER"/> </bean> </beans>
PHP Code:package testjmsreceiver;
import java.util.Random;
import javax.jms.*;
import org.slf4j.*;
import org.springframework.transaction.PlatformTransactionManager;
public class MessageListenerConsumer implements MessageListener {
static final Logger logger = LoggerFactory.getLogger(MessageListenerConsumer.class);
private final PlatformTransactionManager transactionManager;
public MessageListenerConsumer(PlatformTransactionManager transactionManager) {
this.transactionManager = transactionManager;
}
public void onMessage(Message msg) {
try {
TextMessage message = (TextMessage) msg;
String text = message.getText();
int sleepTime = new Random().nextInt(25000);
logger.info("Received message {}. Sleeping {}s", text, sleepTime / 1000);
Thread.sleep(sleepTime);
if (new Random().nextInt(5) == 0) {
logger.info("Message {}: rollback", text);
transactionManager.rollback(transactionManager.getTransaction(null));
// transactionManager.getTransaction(null).setRollbackOnly();//Does not work
} else {
logger.info("Message {}: commit", text);
}
} catch (Exception ex) {
logger.error("error", ex);
}
}
}


Reply With Quote