Announcement Announcement Module
Collapse
No announcement yet.
Spring integration flow and XA transactions Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Spring integration flow and XA transactions

    Hi

    I need to add XA transaction for my flow. It is -
    - read message from JMS
    - DB1 request
    - Enrich some data
    - DB2 request
    - send result to output channel

    How can I do it. I've not found any documentation about XA at all. Is It feature exists?

  • #2
    Sure, you can plug in Spring's JtaTransactionManager. Spring Integration relies on exactly the same transaction management as the core Spring Framework.

    Comment


    • #3
      XA means you are using an XA-capable Transaction Manager in Spring Integration Message flows. And since Spring Iintegration relies on core Spring for its transaction support I would suggest tio read http://static.springsource.org/sprin.../#transactions and http://static.springsource.org/sprin...ansaction.html

      Comment


      • #4
        Thanks,

        But for example. My flow may have no custom code. Just spring integration services. How will the transaction manager determine when transaction have to be commited?

        Comment


        • #5
          Once you read about Spring Transaction and transaction support witting Spring Integration message flows you'll be able to answer this question. The problem is that your question although may look simple to you has many variables and practically impossible to answer without asking many follow up questions.
          For example;
          What kind of Message Flow are you building?
          Do you have a sample configuration?
          What custom code are you writing and how is it invoked within Spring Integration message flow? Is it custom code for endpoints or . . .

          Comment


          • #6
            It's quite easy.
            For example I use this flow
            int-jms:message-driven-channel-adapter -to channelA
            channelA - to - int-jdbc:stored-proc-outbound-gateway
            int-jdbc:stored-proc-outbound-gateway - to - channelB
            channelB - to - int-jdbc:stored-proc-outbound-gateway
            int-jdbc:stored-proc-outbound-gateway - to - outputChannel

            For this flow I must have XA transactions for JMS and to DB invocations. I don't use any activators, filters and etc. So I understand that I can to create XA datasource, JTA manager for datasources and JMS resource. I need to commit transaction when flow reaches outputChannel.

            How It can be implemtented?

            Comment


            • #7
              PLease read documentation I included with my replies and if you fill something is unclear let us know. We spend a lot of time writing it to make sure it is helpful to the user's like yourself who are learning the framework. But if you are not going read it there is not much we can do

              Comment


              • #8
                Actually, Oleg, I think he's just asking how to enable the transaction on the Spring Integration components...

                ...and the short answer is to configure the 'transaction-manager' attribute on the JMS message-driven-channel-adapter. As long as your channels are all sync (the default), that JMS receive operation is the beginning of a transaction scope that encompasses the rest of the flow. Also set the acknowledge attribute to 'transacted'.

                Hope that helps.
                -Mark

                Comment


                • #9
                  Hi!

                  Maybe it's out off topic, but on the matter: I recommend read this Dave Syer's article: http://www.javaworld.com/javaworld/j...ns.html?page=1

                  It will change your view on things ;-)

                  Take care,
                  Artem

                  Comment


                  • #10
                    I've read the doc but there are a lot uncleared things
                    Here is my example which I try to run

                    spring integration config
                    Code:
                    <?xml version="1.0" encoding="UTF-8"?>
                    <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                           xmlns:int="http://www.springframework.org/schema/integration"
                           xmlns:jdbc="http://www.springframework.org/schema/jdbc"
                           xmlns:int-jdbc="http://www.springframework.org/schema/integration/jdbc"
                           xmlns:tx="http://www.springframework.org/schema/tx"
                           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd		 
                    		http://www.springframework.org/schema/integration http://www.springframework.org/schema/integration/spring-integration.xsd
                    		http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd
                    		http://www.springframework.org/schema/integration/jdbc http://www.springframework.org/schema/integration/jdbc/spring-integration-jdbc.xsd
                    		  http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
                    
                        <tx:annotation-driven transaction-manager="txManager"/>
                    
                        <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
                            <property name="dataSource" ref="dataSource"/>
                        </bean>
                    
                        <jdbc:embedded-database id="dataSource" type="H2">
                            <jdbc:script location="classpath:db-schema.sql"/>
                        </jdbc:embedded-database>
                    
                        <int:channel id="in"/>
                        <int:channel id="transformChannel"/>
                        <int:channel id="out">
                            <int:queue capacity="10"/>
                        </int:channel>
                    
                        <int-jdbc:outbound-gateway
                                update="insert into message (id, message) values (1,'Hello')"
                                request-channel="in" reply-channel="transformChannel" data-source="dataSource">
                        </int-jdbc:outbound-gateway>
                        <int:transformer input-channel="transformChannel" output-channel="out" ref="myTransformer"/>
                    
                        <bean id="myTransformer" class="xa.MyTransformer">
                        </bean>
                    
                    </beans>

                    Transformer class
                    Code:
                    package xa;
                    
                    import org.springframework.integration.Message;
                    import org.springframework.integration.annotation.Transformer;
                    
                    public class MyTransformer {
                    
                        @Transformer
                        public Message<?> filter(Message<?> message) {
                            throw new IllegalStateException();
                        }
                    }
                    So, I am expecting that transaction will be rollbacked and the table will be clean. But It doesn't happened. Table has row.

                    Comment


                    • #11
                      Hello

                      I don't see any place in your code, when you start transaction...
                      How do you place the Message into in channel? It should be a point to start transaction.
                      And this transaction will be ended on sending Message into out channel, or rollbacked as you do in the trasformer method.

                      Please, provide more info around you code.

                      Cheers,
                      Artem Bilan

                      Comment


                      • #12
                        This is a question. Who to start transaction if my flow doesn't have any custom code?

                        Comment


                        • #13
                          Who to start transaction if my flow doesn't have any custom code?
                          H-m-m.
                          Sorry, I ask again: how do you send Message into in channel or who does it?

                          There are a lot of solutions:
                          1. from <transactional> <poller> on queue channel
                          2. from @Transactional @Gateway method
                          3. from transactional <int-jms:message-driven-channel-adapter> as Mark said above
                          4. from transactional POJO service via @Gateway.
                          5. before Spring Integration 2.2 I used this trick:
                          HTML Code:
                          <tx:advice id="messageProcessorRequiredNewTxAdvice">
                          		<tx:attributes>
                          			<tx:method name="processMessage" propagation="REQUIRES_NEW"/>
                          		</tx:attributes>
                          	</tx:advice>
                          
                          	<bean id="mergeEntityMessageProcessor" class="org.springframework.aop.framework.ProxyFactoryBean">
                          		<property name="target">
                          			<bean class="org.springframework.integration.handler.MethodInvokingMessageProcessor"
                          				  c:targetObject-ref="entityManager" c:methodName="merge"/>
                          		</property>
                          		<property name="interceptorNames" value="messageProcessorRequiredNewTxAdvice"/>
                          	</bean>
                          Since 2.2 we can use <transactional> sub-element on new JPA-adapters.
                          Unfortunately, it's not your case.
                          So, show, please, upstream message-flow: the point when the Message is placed into in channel
                          Last edited by Artem Bilan; Aug 1st, 2012, 07:50 AM.

                          Comment


                          • #14
                            I get messages from int-jms:message-driven-channel-adapter after. In this point I have to start my XA transaction.

                            Comment


                            • #15
                              In this point I have to start my XA transaction
                              Show config, please, and also keep in mind DataSourceTransactionManager isn't XA-manager. Read his JavaDoc, please.
                              You should use here JtaTransactionManager but he will work only on AS container: JBOSS, WebSphere, WebLogic etc...
                              Or read more Dave's article ;-)

                              Comment

                              Working...
                              X