Announcement Announcement Module
Collapse
No announcement yet.
Rollback message, place back on Q if something goes wrong Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Rollback message, place back on Q if something goes wrong

    Hi ppls,

    Ok, so I got my basic channel thing working using jms inbound adapter. I'm successfully consuming threads and routing and everything working beautifully.

    Now I need to make this thing transaction aware. If something goes wrong, it must place the message back on the Q, basically a rollback.

    Whats the best way forward please.

  • #2
    If you're using an inbound-channel-adapter you need to make it's poller transactional

    Code:
    <poller id="poller" default="true" max-messages-per-poll="2">
    		<interval-trigger interval="10000" />
    		<transactional propagation="REQUIRES_NEW" transaction-manager="transactionManager" />
    	</poller>
    and use the appropriate transaction manager. In my case I need a database and JMS transaction to roll back running inside WAS so I use JTATransactionManager

    Code:
    <beans:bean id="transactionManager" class="org.springframework.transaction.jta.JtaTransactionManager">
    	</beans:bean>
    With inbound-channel-adapter it always sends any errors to the error channel (appendix B4) so you also need to pick the message up from there and re-throw it I found.

    Comment


    • #3
      Thanx rhart once again, really appreciate the clarification and excellent pointer, cant wait to give it a try

      Sounds like we doing almost the same type of project, even using WAS. I really appreciate the assistance.

      Comment


      • #4
        It does sounds very similar Happy to help where I can, it'll be my turn soon. When you get this working the next hurdle is that once the message goes back on the JMS queue it will be picked up again and try to be re-processed indefinately! But I wont be spending much time on this at the moment.

        One thing I forgot is that when using WAS it's recommended to use WebSphereUowTransactionManager which is a WebSphere-specific PlatformTransactionManager. I havnt changed this yet.

        Also, if you do need to use XA transactions like I did then I think the database connection needs to be set up in the container and all the JMS config too and looked up via JNDI. I think this is so the app server has control over everything.

        Comment


        • #5
          Thats exactly the same issues I got to work through too. I will definitely share anything once working. Basically, I think, if it fails, we will write it to an error queue instead, so perhaps the rollback then isnt such a good idea for this scenario. Maybe rather remove it from the main queue and place it on a seperate error queue which can be retried using another worker, so it doesnt affect our main worker. I will need to pitch this to the forum to see if this is a configuration or coding thing. We need fast turnaround, so getting a blocked endless q is the last thing we need. But ya, one step at a time I guess.
          Perhaps ask the forum for a strategy around this scenario, there must be a pattern or something to address it.

          Exactly so, I saw that bit about the WS Tx Manager. I will reconfigure it as soon as I move all this onto WAS. Right now I'm developing outside of WAS just to get something working and the fiddley bits out the way. Once I'm happy, I will configure WAS and reconfigure my connections to go JNDI and then start dealing with WAS issues, but at least I know for now my code works, and if anything breaks once I move it over to WAS, its then a WAS specific issue. I'm hoping its a simple reconfigure to JNDI that will do the trick.

          Yup XA is a definite, just to be on the safe side that things get rolled back correctly. We probably have to access to seperate DB's anyways, so that immediately makes XA the right guy for the job.

          Really appreciate the sharing, hope to return the favour as we progress on this.

          Comment


          • #6
            I added the txManager but I think I need something else, I'm getting the following

            Exception in thread "main" org.springframework.beans.factory.BeanCreationExce ption: Error creating bean with name 'transactionManager' defined in class path resource [common.xml]: Invocation of init method failed; nested exception is java.lang.IllegalStateException: No JTA UserTransaction available - specify either 'userTransaction' or 'userTransactionName' or 'transactionManager' or 'transactionManagerName'

            Do i need another implementation class or some other wiring maybe?

            Comment


            • #7
              This is because you're running outside an application server. JTATransactionManager will delegate to the underlying container for the transaction. I think you need to use something like JTOM (http://jotm.objectweb.org/) as well until you're inside WAS but I've never tried it because i've been inside from the start

              Comment


              • #8
                of course duh....so it needs an actual implementation to support the JTA spec, of course. Ok, then I think its time to move this in WAS.

                Comment


                • #9
                  so JTA for DataBase will be

                  <bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryB ean">
                  <property name="jndiName" value="java:comp/env/jdbc/petclinic"/>
                  </bean>


                  <!-- Transaction manager that delegates to JTA (for a transactional JNDI DataSource) -->
                  <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager"> <<<<--THIS WILL BE WebSphereUowTransactionManager for WAS
                  <property name="dataSource" ref="dataSource"/>
                  </bean>

                  And for JMS?

                  Comment


                  • #10
                    Originally posted by dudleygb View Post
                    <bean id="transactionManager" class="org.springframework.transaction.jta.JtaTran sactionManager"> <<<<--THIS WILL BE WebSphereUowTransactionManager for WAS
                    <property name="dataSource" ref="dataSource"/>
                    </bean>
                    You don't need the datasource property here.

                    For JMS it will be
                    Code:
                    <jee:jndi-lookup id="connectionFactory" jndi-name="jms/QueueConnectionFactory" />
                    
                    <jee:jndi-lookup id="Q_ADDRESS_REQUEST" jndi-name="jms/AddressRequestQueue" />
                    in fact you can use jee:jndi-lookup for the database too
                    Code:
                    <jee:jndi-lookup id="dataSource" jndi-name="jdbc/CorpConDb" />

                    Comment


                    • #11
                      Originally posted by dudleygb View Post
                      Thats exactly the same issues I got to work through too. I will definitely share anything once working. Basically, I think, if it fails, we will write it to an error queue instead, so perhaps the rollback then isnt such a good idea for this scenario. Maybe rather remove it from the main queue and place it on a seperate error queue which can be retried using another worker, so it doesnt affect our main worker. I will need to pitch this to the forum to see if this is a configuration or coding thing. We need fast turnaround, so getting a blocked endless q is the last thing we need. But ya, one step at a time I guess.
                      Perhaps ask the forum for a strategy around this scenario, there must be a pattern or something to address it.
                      This is just WAS config http://www.ibm.com/developerworks/we...itheridge.html I know this article is not for WAS 6.1 but the principle is the same. I think this is actually part of the JMS spec. Cant find how to set the retry iterval though

                      Comment


                      • #12
                        of course, yes, the datasource will automatically be picked up because it looks for a 'datasource' entry right?

                        I still kinda prefer puttin it in though, purely because someone else after me who might not know spring, could still kinda figure it out, but yup, I agree.

                        Thanx again for these bits, really appreciate it

                        Comment


                        • #13
                          regarding the looping queue problem, I've been told that you can configure MQ to keep messages on the Q for a specific amount of time, then moves it to an error Q automatically. I will find out from the MQ boffs how and where this is done. I think using JTA for pulling messages off a queue is the safest way to go, especially for critical messages, which simply cannot just be lost or misplaced. For this reason, I def think its the safest to rather rollback and therefore retain the message, so it isnt lost.

                          Comment


                          • #14
                            Lookin' good guys, we can stop reading the forum soon!

                            Just an idea that for the looping problem. If you want to take rotten messages off a queue after a few rollbacks you can add a selective consumer that accepts a message (and does nothing) after it has seen it enough times. This will trick Spring Integration into believing it was succesfully delivered and not roll back. You can of course then add the message to a dead letter channel instead of just dropping it to the pavement.

                            Of course you can let your jms broker take care of this too...

                            Comment


                            • #15
                              just chatted to another colleague, and they dont worry about rollbacks.
                              they use a topic, which requires the message be read twice before it removes it from the Q. This is very safe. The first read you try process the message. If it fails, you place it on an error Q and read the message a second time to remove it from the in-processing topic.
                              If processing is successful, , read the message a second time so it removes it from the topic. i think this is a very safe way of ensuring no messages are dropped to the pavement And just in case you dont want to trust the Webshpere JMS rollback...
                              Once on the error Q, u can inspect the issue and then push all messages back to the in-processing topic to be retried. What you guys think!?

                              Comment

                              Working...
                              X