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

  • Spring, Spring Integration, transactions and annotations

    Hi,

    I have a very strange problem. Although I don't have an example to reproduce this yet (which I'm creating) I thought I would ask first in general terms to see if there's a simple resolution or if it is a known issue. It could be me that's doing something wrong.

    Essentially I have annotated a bean as @Transactional and I do have <tx:annotation-driven /> in my context as well. The bean itself is lazily loading an entity property. When this bean is declared as a service activator it fails saying that no session is open. When that service activator line is commented out it succeeds. The same thing happens with @Autowired. It works with SI disabled and fails with SI enabled.

    At first impressions it appears as though when SI is enabled any annotations on the endpoints/beans themselves get disregarded / don't get processed. I am in the process of doing a standalone example to try and find out more about what happens. But I have to ask - what is going on here? Is this normal? Is there anything I can try?

    Regarding transactions here's a bit more info on our flow.

    Channels:

    Code:
        <channel id="ch1">
            <queue capacity="50" />
        </channel>
        <channel id="ch2" />
        <channel id="ch3" />
        <channel id="ch4" />
        <channel id="ch5" />
    
        <thread-pool-task-executor id="pool" core-size="6" max-size="12" />
    
        <gateway id="myGateway" service-interface="MyGateway" default-request-channel="ch1" />
    
        <service-activator input-channel="ch1" output-channel="ch2" ref="myThreadForker" method="fork">
            <poller receive-timeout="60000" task-executor="pool">
                <interval-trigger interval="100" />
            </poller>
        </service-activator>
    
        <filter ref="myFilter1" method="filter" input-channel="ch2" output-channel="ch3" />
        <filter ref="myFilter2" method="filter" input-channel="ch3" output-channel="ch4" />
        <service-activator ref="myService1" method="method1" input-channel="ch4" output-channel="ch4" />
        <service-activator ref="myService2" method="method2" input-channel="ch4" />
    It is any or all of the filters and service activators at the bottom that need to be transactional.

    Even if I use direct channels as below the problem still persists.

    Code:
        <channel id="ch1" />
        <channel id="ch2" />
        <channel id="ch3" />
        <channel id="ch4" />
        <channel id="ch5" />
    
        <thread-pool-task-executor id="pool" core-size="6" max-size="12" />
        <gateway id="myGateway" service-interface="MyGateway" default-request-channel="ch1" />
        <filter ref="myFilter1" method="filter" input-channel="ch1" output-channel="ch3" />
        <filter ref="myFilter2" method="filter" input-channel="ch3" output-channel="ch4" />
        <service-activator ref="myService1" method="method1" input-channel="ch4" output-channel="ch4" />
        <service-activator ref="myService2" method="method2" input-channel="ch4" />
    Even if I define the transactions in xml they are still not active. If I comment out the relevant bean from the flow the transactions work in junit context loading integration tests.

    I realise that this is very strange and it is highly likely that this is a problem in my app rather than with the product but not sure what else to try.

    Any thoughts would be much appreciated.

    Thanks.

  • #2
    Although the problem of transactional annotations or xml not being picked up still exists I have managed to get the flow to be transactional by adding a <transactional /> subelement to the poller. Now I have a different problem.

    I presume that the transactional configuration on the poller sets the defaults for each thread. However each endpoint may want to override these defaults. @Transactional annotations are not being picked up on each endpoint (I do have <tx:annotation-driven />. Am I right in thinking that the transactional subelement (as below) will establish defaults for each invocation on a given thread and that endpoints should be able to override it using either annotations or xml? This is not working for me and I'm not sure why.

    Code:
        <channel id="ch1">
            <queue capacity="50" />
        </channel>
        <channel id="ch2" />
        <channel id="ch3" />
        <channel id="ch4" />
        <channel id="ch5" />
    
        <thread-pool-task-executor id="pool" core-size="6" max-size="12" />
    
        <gateway id="myGateway" service-interface="MyGateway" default-request-channel="ch1" />
    
        <service-activator input-channel="ch1" output-channel="ch2" ref="myThreadForker" method="fork">
            <poller receive-timeout="60000" task-executor="pool">
                <interval-trigger interval="100" />
                <transactional transaction-manager="myTxManager" propagation="REQUIRES_NEW" />
            </poller>
        </service-activator>
    
        <filter ref="myFilter1" method="filter" input-channel="ch2" output-channel="ch3" />
        <filter ref="myFilter2" method="filter" input-channel="ch3" output-channel="ch4" />
        <service-activator ref="myService1" method="method1" input-channel="ch4" output-channel="ch4" />
        <service-activator ref="myService2" method="method2" input-channel="ch4" />
    I'm familiar with transactions in Spring where at every layer you can transaction demarcations with custom settings but how is that achieved in a flow? Maybe I'm not thinking clearly. Please feel free to interject :-)

    Comment


    • #3
      One important thing to remember about transactions is that they happen within a single thread. Your "myThreadForker" may break transactional boundaries if it does what I think it does.

      Anyway, if you have a sample we can confirm what is going wrong.

      Comment


      • #4
        I'm using Spring Integration, and I don't understand how can you start, commit and rollback transactions, to be able to resend messages. Any help or suggestions are welcome.
        juanemc2

        Comment

        Working...
        X