Home > Software design >  How to limit transaction scope to just the JPA updating outbound gateway (sort of "auto-commit&
How to limit transaction scope to just the JPA updating outbound gateway (sort of "auto-commit&

Time:10-26

I have an integration flow which starts with a poller. This DOES NOT open a transaction. Down that flow I have a JPA updating outbound gateway:

<int-jpa:updating-outbound-gateway
  request-channel="requestChannel"
  reply-channel="replyChannel"
  named-query="myUpdatingJpqlQuery"
  entity-manager-factory="entityManagerFactory">
  <int-jpa:transactional
    transaction-manager="transactionManager" />
  <int-jpa:parameter name="param1" expression="payload" />
  <int-jpa:parameter name="param2"
    expression="T(java.time.Instant).now()" />
</int-jpa:updating-outbound-gateway>

This works, however, the transaction that this gateway opens embraces the whole downstream flow (unless I break the transaction boundary with an executor). This is not what I want in this case: I would like the transaction to just embrace the updating operation (some sort of "auto-commit"), because the downstream flow will handle transactions in a more granular way and needs to handle independent transactions (not to join an outer one).

This indeed seems to be confirmed by the documentation: https://docs.spring.io/spring-integration/docs/5.4.11/reference/html/messaging-endpoints.html#tx-handle-message-advice

If I understand that linked section well, if I instead use a <request-handler-advice-chain> with a <tx:advice> I should get the desired result.

However, if I use this:

<int-jpa:updating-outbound-gateway
  request-channel="requestChannel"
  reply-channel="replyChannel"
  named-query="myUpdatingJpqlQuery"
  entity-manager-factory="entityManagerFactory">
  <int-jpa:parameter name="param1" expression="payload" />
  <int-jpa:parameter name="param2"
    expression="T(java.time.Instant).now()" />
  <int-jpa:request-handler-advice-chain>
    <tx:advice transaction-manager="transactionManager" />
  </int-jpa:request-handler-advice-chain>
</int-jpa:updating-outbound-gateway>

I get a javax.persistence.TransactionRequiredException, so it seems like that advice is not working (at least not in the way I want).

What is the better way to do this? Am I forced to use a dispatcher with an executor on the reply channel to break the transaction boundary?

CodePudding user response:

Make it like this:

<tx:advice>
    <tx:attributes>
        <tx:method name="*"/>
    </tx:attributes>
</tx:advice>

It does not have any method matches by default therefore such an advice is not applied to the internal AdvisedRequestHandler.

  • Related