Announcement Announcement Module
Collapse
No announcement yet.
DefaultMessageListenerContainer and Websphere default JMS provider (SIB) Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Fair enough, I think the problems with sessionTransacted=false are websphere issues and I will pursue those through websphere support. What about the errors reported by websphere when using sessionTransacted=true:

    Code:
    [2/22/12 16:53:21:233 PST] 00000026 LocalTransact E   enlist(): It is NOT valid to continue working under a transaction that has already rolledback
    
    [2/22/12 16:53:21:233 PST] 00000025 LocalTransact E   enlist(): It is NOT valid to continue working under a transaction that has already rolledback
    
    [2/22/12 16:53:21:243 PST] 00000025 ConnectionEve E   J2CA0074E: Unable to enlist connection from resource mdptest/ConnectionFactory with current transaction in method localTransactionStarted due to exception. Initiating destruction of connection. Exception is: javax.resource.ResourceException: Attempt to continue working after transaction rolledback !
    
    	at com.ibm.ejs.j2c.LocalTransactionWrapper.enlist(LocalTransactionWrapper.java:577)
    
    	at com.ibm.ejs.j2c.ConnectionEventListener.localTransactionStarted(ConnectionEventListener.java:845)
    
    	at com.ibm.ws.sib.api.jmsra.impl.JmsJcaManagedConnection.localTransactionStarted(JmsJcaManagedConnection.java:929)
    
    	at com.ibm.ws.sib.api.jmsra.impl.JmsJcaSessionImpl.getCurrentTransaction(JmsJcaSessionImpl.java:323)
    
    	at com.ibm.ws.sib.api.jms.impl.JmsSessionImpl.getTransaction(JmsSessionImpl.java:1823)
    
    	at com.ibm.ws.sib.api.jms.impl.JmsMsgConsumerImpl.receiveInboundMessage(JmsMsgConsumerImpl.java:1051)
    
    	at com.ibm.ws.sib.api.jms.impl.JmsMsgConsumerImpl.receive(JmsMsgConsumerImpl.java:481)
    
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:405)
    
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:308)
    
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:261)
    
    	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982)
    
    	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:881)
    
    	at org.springframework.scheduling.commonj.DelegatingWork.run(DelegatingWork.java:61)
    
    	at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1178)
    
    	at com.ibm.ws.asynchbeans.WorkWithExecutionContextImpl.go(WorkWithExecutionContextImpl.java:199)
    
    	at com.ibm.ws.asynchbeans.CJWorkItemImpl.run(CJWorkItemImpl.java:236)
    
    	at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1650)
    
    
    
    [2/22/12 16:53:21:246 PST] 00000025 ConnectionEve W   J2CA0206W: A connection error occurred.  To help determine the problem, enable the Diagnose Connection Usage option on the Connection Factory or Data Source.
    
    [2/22/12 16:53:21:246 PST] 00000025 ConnectionEve A   J2CA0216I: The Connection Manager received a fatal connection error from the Resource Adapter for resource mdptest/ConnectionFactory. Information may be available in previous messages or exceptions.
    
    [2/22/12 16:53:21:233 PST] 0000001f LocalTranCoor W   WLTC0033W: Resource mdptest/ConnectionFactory rolled back in cleanup of LocalTransactionContainment.
    
    [2/22/12 16:53:21:233 PST] 00000020 LocalTranCoor W   WLTC0033W: Resource mdptest/ConnectionFactory rolled back in cleanup of LocalTransactionContainment.
    
    [2/22/12 16:53:21:284 PST] 00000020 LocalTranCoor W   WLTC0032W: One or more local transaction resources were rolled back during the cleanup of a LocalTransactionContainment.
    
    [2/22/12 16:53:21:284 PST] 0000001f LocalTranCoor W   WLTC0032W: One or more local transaction resources were rolled back during the cleanup of a LocalTransactionContainment.
    
    [2/22/12 16:53:21:291 PST] 00000026 DMAdapter     I com.ibm.ws.ffdc.impl.DMAdapter getAnalysisEngine FFDC1009I: Analysis Engine using data base: D:\IBM\WebSphere\AppServer80\profiles\MdpTestAppSrv\properties\logbr\ffdc\adv\ffdcdb.xml
    
    [2/22/12 16:53:21:345 PST] 00000026 FfdcProvider  W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on D:\IBM\WebSphere\AppServer80\profiles\MdpTestAppSrv\logs\ffdc\server1_2148f49_12.02.22_16.53.21.2828093985449575169709.txt com.ibm.ejs.j2c.ConnectionEventListener.localTransactionStarted 481
    
    [2/22/12 16:53:21:346 PST] 00000026 ConnectionEve E   J2CA0074E: Unable to enlist connection from resource mdptest/ConnectionFactory with current transaction in method localTransactionStarted due to exception. Initiating destruction of connection. Exception is: javax.resource.ResourceException: Attempt to continue working after transaction rolledback !
    
    	at com.ibm.ejs.j2c.LocalTransactionWrapper.enlist(LocalTransactionWrapper.java:577)
    
    	at com.ibm.ejs.j2c.ConnectionEventListener.localTransactionStarted(ConnectionEventListener.java:845)
    
    	at com.ibm.ws.sib.api.jmsra.impl.JmsJcaManagedConnection.localTransactionStarted(JmsJcaManagedConnection.java:929)
    
    	at com.ibm.ws.sib.api.jmsra.impl.JmsJcaSessionImpl.getCurrentTransaction(JmsJcaSessionImpl.java:323)
    
    	at com.ibm.ws.sib.api.jms.impl.JmsSessionImpl.getTransaction(JmsSessionImpl.java:1823)
    
    	at com.ibm.ws.sib.api.jms.impl.JmsMsgConsumerImpl.receiveInboundMessage(JmsMsgConsumerImpl.java:1051)
    
    	at com.ibm.ws.sib.api.jms.impl.JmsMsgConsumerImpl.receive(JmsMsgConsumerImpl.java:481)
    
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveMessage(AbstractPollingMessageListenerContainer.java:405)
    
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.doReceiveAndExecute(AbstractPollingMessageListenerContainer.java:308)
    
    	at org.springframework.jms.listener.AbstractPollingMessageListenerContainer.receiveAndExecute(AbstractPollingMessageListenerContainer.java:261)
    
    	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.invokeListener(DefaultMessageListenerContainer.java:982)
    
    	at org.springframework.jms.listener.DefaultMessageListenerContainer$AsyncMessageListenerInvoker.run(DefaultMessageListenerContainer.java:881)
    
    	at org.springframework.scheduling.commonj.DelegatingWork.run(DelegatingWork.java:61)
    
    	at com.ibm.ws.asynchbeans.J2EEContext.run(J2EEContext.java:1178)
    
    	at com.ibm.ws.asynchbeans.WorkWithExecutionContextImpl.go(WorkWithExecutionContextImpl.java:199)
    
    	at com.ibm.ws.asynchbeans.CJWorkItemImpl.run(CJWorkItemImpl.java:236)
    
    	at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1650)
    Any ideas what's going on there? It seems like websphere is trying to rollback a transaction on each poll.

    Comment


    • #17
      The javaworld article is an interesting read. If I understand correctly, the "Best Effort 1PC Pattern" will only be applied using a message listener that updates a database when sessionTransacted=true or JmsTransactionManager is used, else there's no transaction on the JMS Session and so it can never rollback when the database transaction fails. This is why messages are "retried" when an unchecked exception is thrown from a message listener's onMessage when sessionTransacted=true or a transaction manager is used, but are not retried otherwise. Is that correct?

      Comment


      • #18
        That is correct; if there's no JMS transaction in process, there's nothing to synchronize and the JDBC transaction stands alone (commits or rolls back depending on what happens within its scope).

        Comment


        • #19
          You stated earlier that with the default auto acknowledge mode, sessionTransacted set to false and no transactionManager, you may lose messages if you crash... Is that situation limited to JVM crashes and anything that might go wrong in the message listener? What I'm getting at is ignoring the jvm crash situation, is there a potential for something to go wrong in the JMS infrastructure such that a message never gets to the message listener but is acknowledged and never resent?

          Given the DMLC configuration described above, if you have a message listener that saves data to a database based on instructions in the message, an exception from the JDBC code will not roll back the message for retry, but if the message listener code is written such that all exceptions are handled appropriately, I would not want any retries since they would be destined to repeatedly fail. Retrying messages after message listener failure seems to me to be the major driver for using JMS transactions, and since in many cases I don't want to see retries for messages that my code has already processed and that has failed for reasons that won't be corrected, I have mostly avoided JMS transactions. However, if there are cases where the message listener might never get called (again ignoring the JVM crash situation) yet the message is considered "delivered and acknowledged", then I will probably need to reconsider that.

          Comment


          • #20
            hang on a second. See this page:

            http://publib.boulder.ibm.com/infoce...tmj_desap.html

            Applications must not cache JMS connections, sessions, producers or consumers. WebSphere Application Server closes these objects when a bean or servlet completes, and so any attempt to use a cached object will fail with a javax.jms.IllegalStateException exception.
            Perhaps Websphere hates it when Spring tries to cache Sessions and Consumers? I'll try testing various DMLC transaction-related configurations (sessionTransacted=true, false) with cacheLevelName set to CACHE_NONE and see if my problems persist.

            Comment


            • #21
              Right; it's not just limited to JVM crashes. If you read the JavaDocs for Session, you will see that AUTO_ACKNOWLEDGE mode acks the message as soon as receive() returns.

              Given that the DMLC uses receive() to get the messages, any failure after that time will cause the message to be lost.

              You could configure the retry policy on your broker to send the message to a DLQ after 0 retries.

              Or, I believe that what you want (transactions to avoid lost messages, but no retries), can easily be accomplished by giving the DMLC a reference to a custom ErrorHandler...

              Code:
              public interface ErrorHandler {
              
              	void handleError(Throwable t);
              
              }
              Where you can consume and/or log the exception. If you return without throwing an exception, the transaction will be committed.

              Comment


              • #22
                OK, I believe I've nailed down the cause of the problems. The Websphere default messaging provider does not work with any of the DMLC caching strategies under any circumstances.

                When sessionTransacted=false and cacheLevel=CACHE_AUTO, DMLC tries to cache connections, sessions, and consumers. On Websphere with the default messaging provider, this results in a memory leak.

                When sessionTransacted=true and cacheLevel=CACHE_AUTO, DMLC again tries to cache connections, sessions, and consumers. This results in exceptions about illegal resource states and rollbacks.

                When I set cacheLevel to CACHE_NONE with sessionTransacted true or false, I don't see any connection leak. The last thing I need to look at is how Weblogic works with CACHE_NONE.

                Comment


                • #23
                  One more question. What is the difference between sessionTransacted and JmsTransactionManager?

                  Comment


                  • #24
                    ErrorHandler is only available in Spring 3.0+. Is there something equivalent in 2.5.6?

                    Comment


                    • #25
                      connection thrashing when using TransactionAwareConnectionFactoryProxy

                      When using TransactionAwareConnectionFactoryProxy and DMLC pointed to a DataSourceTransactionManager, I see the following spring trace logging on every DMLC polling interval:

                      Code:
                      2012-02-28 11:06:34,107 DEBUG:org.springframework.transaction.support.AbstractPlatformTransactionManager - Creating new transaction with name [messageListenerContainer]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
                      2012-02-28 11:06:34,107 DEBUG:org.springframework.transaction.support.AbstractPlatformTransactionManager - Creating new transaction with name [messageListenerContainer]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
                      2012-02-28 11:06:34,107 DEBUG:org.springframework.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [jdbc:derby://localhost:1527/mdptest, UserName=MdpTest, Apache Derby Network Client JDBC Driver] for JDBC transaction
                      2012-02-28 11:06:34,107 DEBUG:org.springframework.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [jdbc:derby://localhost:1527/mdptest, UserName=MdpTest, Apache Derby Network Client JDBC Driver] to manual commit
                      2012-02-28 11:06:34,108 TRACE:org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@d175ff] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@1360c93] to thread [messageListenerContainer-2]
                      2012-02-28 11:06:34,108 TRACE:org.springframework.transaction.support.TransactionSynchronizationManager - Initializing transaction synchronization
                      2012-02-28 11:06:34,107 DEBUG:org.springframework.jdbc.datasource.DataSourceTransactionManager - Acquired Connection [jdbc:derby://localhost:1527/mdptest, UserName=MdpTest, Apache Derby Network Client JDBC Driver] for JDBC transaction
                      2012-02-28 11:06:34,108 DEBUG:org.springframework.jdbc.datasource.DataSourceTransactionManager - Switching JDBC Connection [jdbc:derby://localhost:1527/mdptest, UserName=MdpTest, Apache Derby Network Client JDBC Driver] to manual commit
                      2012-02-28 11:06:34,108 TRACE:org.springframework.transaction.support.TransactionSynchronizationManager - Bound value [org.springframework.jdbc.datasource.ConnectionHolder@199f443] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@1360c93] to thread [messageListenerContainer-1]
                      2012-02-28 11:06:34,108 TRACE:org.springframework.transaction.support.TransactionSynchronizationManager - Initializing transaction synchronization
                      2012-02-28 11:06:35,108 TRACE:org.springframework.jms.listener.AbstractPollingMessageListenerContainer - Consumer [ActiveMQMessageConsumer { value=ID:cic-dev-gaa2-62970-1330455967706-2:0:1:1, started=true }] of session [ActiveMQSession {id=ID:cic-dev-gaa2-62970-1330455967706-2:0:1,started=true}] did not receive a message
                      2012-02-28 11:06:35,108 TRACE:org.springframework.jms.listener.AbstractPollingMessageListenerContainer - Consumer [ActiveMQMessageConsumer { value=ID:cic-dev-gaa2-62970-1330455967706-2:0:2:1, started=true }] of session [ActiveMQSession {id=ID:cic-dev-gaa2-62970-1330455967706-2:0:2,started=true}] did not receive a message
                      2012-02-28 11:06:35,108 TRACE:org.springframework.transaction.support.AbstractPlatformTransactionManager - Triggering beforeCommit synchronization
                      2012-02-28 11:06:35,108 TRACE:org.springframework.transaction.support.AbstractPlatformTransactionManager - Triggering beforeCommit synchronization
                      2012-02-28 11:06:35,108 TRACE:org.springframework.transaction.support.AbstractPlatformTransactionManager - Triggering beforeCompletion synchronization
                      2012-02-28 11:06:35,109 DEBUG:org.springframework.transaction.support.AbstractPlatformTransactionManager - Initiating transaction commit
                      2012-02-28 11:06:35,109 DEBUG:org.springframework.jdbc.datasource.DataSourceTransactionManager - Committing JDBC transaction on Connection [jdbc:derby://localhost:1527/mdptest, UserName=MdpTest, Apache Derby Network Client JDBC Driver]
                      2012-02-28 11:06:35,109 TRACE:org.springframework.transaction.support.AbstractPlatformTransactionManager - Triggering beforeCompletion synchronization
                      2012-02-28 11:06:35,109 DEBUG:org.springframework.transaction.support.AbstractPlatformTransactionManager - Initiating transaction commit
                      2012-02-28 11:06:35,109 DEBUG:org.springframework.jdbc.datasource.DataSourceTransactionManager - Committing JDBC transaction on Connection [jdbc:derby://localhost:1527/mdptest, UserName=MdpTest, Apache Derby Network Client JDBC Driver]
                      2012-02-28 11:06:35,109 TRACE:org.springframework.transaction.support.AbstractPlatformTransactionManager - Triggering afterCommit synchronization
                      2012-02-28 11:06:35,109 TRACE:org.springframework.transaction.support.AbstractPlatformTransactionManager - Triggering afterCommit synchronization
                      2012-02-28 11:06:35,109 TRACE:org.springframework.transaction.support.AbstractPlatformTransactionManager - Triggering afterCompletion synchronization
                      2012-02-28 11:06:35,110 TRACE:org.springframework.transaction.support.TransactionSynchronizationManager - Clearing transaction synchronization
                      2012-02-28 11:06:35,109 TRACE:org.springframework.transaction.support.AbstractPlatformTransactionManager - Triggering afterCompletion synchronization
                      2012-02-28 11:06:35,110 TRACE:org.springframework.transaction.support.TransactionSynchronizationManager - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@d175ff] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@1360c93] from thread [messageListenerContainer-2]
                      2012-02-28 11:06:35,110 DEBUG:org.springframework.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [jdbc:derby://localhost:1527/mdptest, UserName=MdpTest, Apache Derby Network Client JDBC Driver] after transaction
                      2012-02-28 11:06:35,110 DEBUG:org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
                      2012-02-28 11:06:35,110 TRACE:org.springframework.transaction.support.TransactionSynchronizationManager - Clearing transaction synchronization
                      2012-02-28 11:06:35,110 DEBUG:org.springframework.transaction.support.AbstractPlatformTransactionManager - Creating new transaction with name [messageListenerContainer]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
                      2012-02-28 11:06:35,110 TRACE:org.springframework.transaction.support.TransactionSynchronizationManager - Removed value [org.springframework.jdbc.datasource.ConnectionHolder@199f443] for key [org.apache.tomcat.dbcp.dbcp.BasicDataSource@1360c93] from thread [messageListenerContainer-1]
                      2012-02-28 11:06:35,110 DEBUG:org.springframework.jdbc.datasource.DataSourceTransactionManager - Releasing JDBC Connection [jdbc:derby://localhost:1527/mdptest, UserName=MdpTest, Apache Derby Network Client JDBC Driver] after transaction
                      2012-02-28 11:06:35,110 DEBUG:org.springframework.jdbc.datasource.DataSourceUtils - Returning JDBC Connection to DataSource
                      Does this mean that for every DMLC poll, a connection is obtained from the DataSource and committed? Doesn't that create a lot of connection thrashing, even when no message is received and no database work is done?

                      Comment

                      Working...
                      X