Announcement Announcement Module
No announcement yet.
transaction management in SI Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • transaction management in SI

    <int-poller fixed-rate="60000">
    <int:chain input-channel="responseChannel" output-channel="transformedChannel">
    <int:filter ref="fb" method="filter" discard-channel="rejectedChannel" />
    <int:transformer ref="tb"/>
    <int-publish-subscribe-channel id="transformedChannel">
    <int:wire-tap channel="stdout"/>
    <stream:stdout-channel-adapter id="rejectedChannel" charset="UTF-8" append-newline="true"/>
    I need some help on understanding transactions in spring integration.

    Above config is trying to do these 4 tasks -

    1)Poll database x
    2)Insert selected rows into database y
    3) call a stored procedure in database y to let them do something with these rows
    4) when 1,2,3 are good, mark all rows as processed (update status column) in database x

    I want to put 2,3 under one transaction and make #4 depending upon success of this transaction.

    since i need all rows to perform 2,3,4 so i have used a publish/subscribe model, not sure if there is a better model to achieve this.

    Thanks for your help.
    Last edited by rosadom; Jun 3rd, 2014, 04:15 PM.

  • #2
    As written, this will all run in one transaction.

    It's not entirely clear why you want to do 4 in a different transaction to 2, 3 but to do that you would need to start a new transaction. Probably the simplest way to do that is to add a new method to otherDatabaseAdapter and mark it @Transactional(propagation=Propagation.REQUIRES_NE W) and have it invoke the other two methods.

    If you want to keep them separate and do it all in Spring Integration, you would have to insert a transactional <gateway/> and run 2 and 3 in it's subflow. A transactional gateway is simply a <gateway/> with its service interface marked as @Transactional and invoked via a <service-activator/>.

    @Transactional(propagation=Propagation.REQUIRES_NE W)
    void doInTransaction(Message<?> message);


    • #3
      Thanks Gary,
      Ideally i would like to run this as one translation, so does that mean i can safely eliminate #4 and put update query in my jdbc:inbound-channel-adapter itself (instead of #4) and this runs in one transaction?
      The main point for me to consider that #1 and #2 are one database and #2 and #3 are different database and i don't want to get into distributed transactions.
      My application can tolerate duplicate data flow, so most important thing in this flow for me is to make sure #4 only happens when #2 and #3 are success.

      Thanks for your help.


      • #4
        That's a bit more tricky; you don't show your TransactionManager(s). By default, the <transactional/> advice will start a transaction for the "transactionManager" bean.

        If that's the txManager for 2,3, it means the inbound adapter won't run in a transaction at all.

        Instead of using <transactional />, you should be able to use <advice-chain/> instead, containing two <tx:advice/> beans, one for each transaction manager; that way, the "outer" (first) transaction will only be committed if the second one commits (and they will be committed as close together as possible).

        If you turn on TRACE debugging for org.springframwork.transaction you should see the commit/rollback activity.


        • #5
          Thanks Gary, This is useful to know how to enable this logging.

          I have a txManager for 2, 3.

          #1 and #4 are run in independent transactions. Even if #4 failed after sucess on #2 and #3, the process is OK with that situation.

          I understand that publish/subscribe channel, the order of subscription will determine what is executed first.
          So order 1 goes first and only when its successful order 2 will be executed and so on, is that right?

          Last edited by rosadom; Jun 5th, 2014, 10:06 AM.


          • Artem Bilan
            Artem Bilan commented
            Editing a comment
            Correct. And if any subscription will fail any prevoius will rolled back, too. Of course, if your publish-subscribe channel is single threaded

        • #6
          Thanks Artem, how do you make publish-subscribe channel single threaded? Thanks


          • Artem Bilan
            Artem Bilan commented
            Editing a comment
            It is single-threaded by default. However all your subscribers should be single-threaded, too. Otherwise you won't get transaction boundries, anyway.
            For this purpose all your subflows should be wired via DirrectChannels

        • #7
          #1 and #4 are run in independent transactions.
          Just to be clear, if the transaction manager is for 2 and 3, 4 might run in its own transaction (if it's marked @Transactional). But 1 will not be transactional at all (and 4 won't be transactional if it's not annotated @Transactional).

          However, since they are single sql queries that only use 1 table, it's semantics - but I just want it to be clear that 1 and 4 are not actually running in a transaction unless you apply a txAdvice for both transaction managers.