Announcement Announcement Module
Collapse
No announcement yet.
DMLC closes shared connection Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • DMLC closes shared connection

    Hello,

    I am trying to use DMLC with Webspere MQ and XA transaction (I use spring 2.5.4). I am trying to figure out the right DMLC configuration. I have set the cache level to CACHE_CONNECTION. The problem is that the JMS connection is closed after each iteration. At the following iteration I get the following error:
    Code:
    javax.jms.IllegalStateException: MQJMS1004: Connexion fermée.
    	at com.ibm.mq.jms.MQQueueConnection.createQueueSession(MQQueueConnection.java:374)
    	at com.ibm.mq.jms.MQQueueConnection.createQueueSession(MQQueueConnection.java:234)
    	at com.ibm.mq.jms.MQQueueConnection.createSession(MQQueueConnection.java:579)
    	at org.springframework.jms.support.JmsAccessor.createSession(JmsAccessor.java:196)
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.access$200(AbstractPollingMessageListenerContainer.java:77)
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer$MessageListenerContainerResourceFactory.createSession(AbstractPollingMessageListenerContainer.java:504)
    	at org.springframework.jms.connection.ConnectionFactoryUtils.doGetTransactionalSession(ConnectionFactoryUtils.java:282)
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:285)
    	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 have debugged for a while and I think the error comes from the fact that when creating the session, it is automatically registered within the transaction manager and it will be closed once the transaction is finished (in AbstractPollingMessageListenerContainer.doReceiveA ndExecute, the method ConnectionFactoryUtils.doGetTransactionalSession is used for creating the session and it registers the JmsResourceSynchronization which will always close the shared connection). Could this be a bug in the AbstractPollingMessageListenerContainer or maybe there there is a mistake in my DMLC configuration?

    Here is my DMLC configuration:
    Code:
    <bean id="jmsListenerContainer" class="org.springframework.jms.listener.DefaultMessageListenerContainer" >
    <property name="connectionFactory" ref="jndiXaConnectionFactory"/>
    <property name="destinationName" value="${JMS_INPUT_DESTINATION}"/>
    <property name="transactionManager" ref="transactionManager"/>
    <property name="maxConcurrentConsumers" value="${JMS_CONSUMERS}"/>
    <property name="receiveTimeout" value="${JMS_RECEIVE_TIMEOUT}"/>
    <property name="cacheLevelName" value="CACHE_CONNECTION"/>
    </bean>
    Regards,
    Mihai

  • #2
    Spring documentation is quite clear about cache level and external transactions usage - DefaultMessageListenerContainer.setCacheLevel():
    Specify the level of caching that this listener container is allowed to apply.

    Default is CACHE_NONE if an external transaction manager has been specified (to reobtain all resources freshly within the scope of the external transaction), and CACHE_CONSUMER else (operating with local JMS resources).

    Some J2EE servers only register their JMS resources with an ongoing XA transaction in case of a freshly obtained JMS Connection and Session, which is why this listener container does by default not cache any of those. However, if you want to optimize for a specific server, consider switching this setting to at least CACHE_CONNECTION or CACHE_SESSION even in conjunction with an external transaction manager.

    Currently known servers that absolutely require CACHE_NONE for XA transaction processing: JBoss 4. For any others, consider raising the cache level.
    So, you should check Websphere documentation is order to find out JMS resources JTA transaction participation rules and define necessary cache level or just not to change default property value.

    Comment


    • #3
      Hello Denis,

      Thank you for you quick reply. I shall read again the Websphere documentation just to double check this.

      However I think it is quite wierd to register the shared connection with the current transaction (using the spring spring Transaction Manager) and then close it once the transaction has finished - on afterCompletion. I do not see how this may work in case of concurent consumers (independently of the JMS provider). Do you know if anybody has used the CACHE_CONNECTION before?

      Regards,
      Mihai

      Comment


      • #4
        Originally posted by msardarescu View Post
        However I think it is quite wierd to register the shared connection with the current transaction (using the spring spring Transaction Manager) and then close it once the transaction has finished - on afterCompletion.
        You invert the process here You want to use JTA transaction and that's the backbone (Spring's JtaTransactionManager just delegates to the underlying JTA provider). That provider may obey new connection per new transaction usage but you violate that via setting cache level to CACHE_CONNECTION. So, you just don't follow the rules of the used JTA provider here.


        Originally posted by msardarescu View Post
        I do not see how this may work in case of concurent consumers (independently of the JMS provider). Do you know if anybody has used the CACHE_CONNECTION before?

        Regards,
        Mihai
        I'm afraid your concern is not clear for me You're free to define any suitable caching level at the pure jms communications (without jta) and have to follow the rules implied by particular jta provider usage.

        Comment


        • #5
          Hello Denis,

          I think I did not explain correctly the problem I encountered.

          I need to read a message from a JMS Queue do some processing and insert it into a database. I would like to do all this in an XA transaction. I am concerned with the performace so I am trying to figure out how I could tune the DMLC to make it go faster.

          I have tested different DMLC configurations and I stumbled upon the problem that the shared connection is closed at the end of each transaction. After some investigations, it seems that the DMLC registers the newly created session with the current transaction using the TransactionSynchronizationManager (please see the ConnectionFactoryUtils.doGetTransactionalSession method).
          Code:
          TransactionSynchronizationManager.registerSynchronization(
          					new JmsResourceSynchronization(
          							connectionFactory, resourceHolderToUse, resourceFactory.isSynchedLocalTransactionAllowed()));
          			resourceHolderToUse.setSynchronizedWithTransaction(true);
          			TransactionSynchronizationManager.bindResource(connectionFactory, resourceHolderToUse);
          Once the transaction is commited, the connection will be closed (even if it is shared). I think that this is a potential bug . Normally, if the JMS connection is shared (CACHE_SESSION), one would expect it not to be closed after each message, but rather kept open for the entire DMLC life.

          Regards,
          Mihai

          Comment


          • #6
            Oh, I see your point now. I looked through the Spring jms code and it seems that there is really no way to keep a shared connection with non-transacted session that participates in distributed transaction.

            However, I can't be 100% sure about that at the moment. It's necessary to spend additional time to check the processing. I'm interested in that and will do that when possible.

            Comment

            Working...
            X