Mark1234
Mark1234

Reputation: 619

using gateway for starting transaction

I have been following previous answers that talk about inserting gateway / service-activator to start a new transaction mid way in SI processing. I have tried below code but for some reason it does not work, if you could point to error in this configuration please.

All the threads seems to be waiting for something to happen and the sp outbound gateway is not invoked, but i cant figure out what.

The idea here is to process each task produced by splitter in a thread pool under a new transaction.

<int:splitter...output-channel="taskChannel"/>
<int:channel id="taskChannel">
        <int:dispatcher task-executor="taskExecutor"/>               
</int:channel>       
<int:gateway id="txGw"  service-interface="com.some.test.StartTransactionalGateway"
    default-request-channel="taskChannel" default-reply-channel="individualTask">                               
    </int:gateway>      
<int:service-activator ref="txGw" 
            input-channel="taskChannel"
            output-channel="individualTask" 
            method="startTx"
            auto-startup="true">
</int:service-activator>            

<int-jdbc:stored-proc-outbound-gateway ...request-channel="individualTask" .....

interface StartTransactionalGateway {
     @Transactional 
     Message<?> startTx(Message<?> m);

}

Upvotes: 0

Views: 1391

Answers (2)

Artem Bilan
Artem Bilan

Reputation: 121272

Well, Don't forget that you can mark something transactional not only using @Transactional annotation. There is <tx:advice> for the XML declaration.

If you need to wrap to the TX just only that <int-jdbc:stored-proc-outbound-gateway>, there is <request-handler-advice> sub-element to wrap the handleRequestMessage of the underlying component to any Advice:

<int-jdbc:request-handler-advice-chain>
    <tx:advice>
        <tx:attributes>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>
</int-jdbc:request-handler-advice-chain>

From other side your code can not work, because <int-jdbc:stored-proc-outbound-gateway> may not return result. The procedure is one-way. But the <gateway> interface is request-reply.

UPDATE

See my answer here Keep transaction within Spring Integration flow. It is another trick how to make down-stream flow transactional.

With <gateway> you should be sure that your transactional subflow returns to the replyChannel in the end. Or... Make your gateway's method as void to achieve one-way behaviour.

Upvotes: 1

Gary Russell
Gary Russell

Reputation: 174564

default-request-channel="taskChannel" the gateway is sending messages to itself.

You can't mix channels in the subflow with the main channels. You need something like...

<int:splitter...output-channel="taskChannel"/>

<int:channel id="taskChannel">
    <int:dispatcher task-executor="taskExecutor"/>               
</int:channel>       

<int:service-activator ref="txGw" 
        input-channel="taskChannel"
        output-channel="whereWeWantTheResultsToGo" 
        method="startTx"
        reply-timeout="0"
        auto-startup="true" />

<int:gateway id="txGw"  service-interface="com.some.test.StartTransactionalGateway"
    default-request-channel="toStoredProc" />                               

<int-jdbc:stored-proc-outbound-gateway ...request-channel="toStoredProd" .....

You don't need a default-reply-channel; simply omit the reply-channel on the stored proc gateway and the reply will automatically go back.

Upvotes: 1

Related Questions