Store transaction in Spring integration thread

Inboud gateway:

<int-http:inbound-gateway id="inbound.gateway" request-channel="transactional.channel.input" reply-channel="channel.output" error-channel="channel.error" request-payload-type="java.lang.String" </int-http:inbound-gateway> 

Definition of recommendation:

 <tx:advice id="advice"> <tx:attributes> <tx:method name="send" propagation="REQUIRES_NEW" rollback-for="MyClassException"/> </tx:attributes> </tx:advice> 

Config tip:

 <aop:config> <aop:advisor advice-ref="advice" pointcut="bean(transactional.channel.input)"/> </aop:config> 

The chain that should be transactional:

 <int:chain input-channel="transactional.channel.input" output-channel="non.transactional.channel.input> <int:service-activator ref="v1.registerUser.service" method="registerUser"/> <int:service-activator ref="v1.saveObject.service" method="saveObject"/> </int:chain> 

The chain for which you want to complete the transaction earlier in order to get the identifier of the object generated at the last step of the transaction:

 <int:chain input-channel="non.transactional.channel.input" output-channel="channel.output"> <int:service-activator ref="v1.getObjectId.service" method="getObjectId"/> <int:object-to-json-transformer/> </int:chain> 

Having this simplified context, when I access the id in the getObjectId service, the transaction failed.

Thus, the transaction seems to be running at the output level of the inbound-gateway.

+4
source share
2 answers

Another awesome trick without writing Java code:

 <channel id="input"/> <aop:config> <aop:advisor advice-ref="txAdvice" pointcut="bean(input)"/> </aop:config> <tx:advice id="txAdvice"> <tx:attributes> <tx:method name="send"/> </tx:attributes> </tx:advice> 

In this case, your entire stream of streams with a one-way stream will be transferred to TX when sending a message to the input channel

+9
source

If MessagingGateway is entered into your code, you can simply start the transaction on the gateway, and since all channels are direct, the entire stream will work in one transaction. Just add your gateway method using @Transactional and add <tx:annotation-driven/> or @EnableTransactionManagement to your context (and transaction manager).

Or you can start your transaction even earlier if you want other things in the transaction ...

 @Transactional public void foo() { ... Object reply = myGateway.exchange(Object foo); ... } 

Just remember to call foo() from another bean so that the class containing foo() is wrapped in a transaction proxy (@EnableTransactionManagement or <tx:annotation-driven/> ).

If it is a gateway, such as an inbound HTTP gateway, add the @Transaction al gateway after the inbound gateway to start the transaction. (Add a service activator that is ref a <gateway/> , which exchanges Message<?> And annotates using @Transactional ).

+4
source

Source: https://habr.com/ru/post/896988/


All Articles