トランザクションサポート

バージョン 5.0 から、HandleMessageAdvice 実装のおかげで、新しい TransactionHandleMessageAdvice が導入され、ダウンストリームフロー全体がトランザクション可能になりました。通常の TransactionInterceptor が <request-handler-advice-chain> 要素で使用されている場合 (たとえば、<tx:advice> を構成することによって)、開始されたトランザクションは内部 AbstractReplyProducingMessageHandler.handleRequestMessage() にのみ適用され、ダウンストリームフローには伝播されません。

XML 構成を簡素化するために、<request-handler-advice-chain> とともに、<transactional> 要素がすべての <outbound-gateway> および <service-activator> および関連コンポーネントに追加されました。次の例は、使用中の <transactional> を示しています。

<int-jdbc:outbound-gateway query="select * from things where id=:headers[id]">
        <int-jdbc:transactional/>
</int-jdbc:outbound-gateway>

<bean id="transactionManager" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="org.springframework.transaction.TransactionManager"/>
</bean>

JPA 統合コンポーネントに精通している場合、このような構成は新しいものではありませんが、<poller> または JMS などのメッセージ駆動型チャネルアダプターだけでなく、フローの任意のポイントからトランザクションを開始できます。

次の例に示すように、Java 構成は TransactionInterceptorBuilder を使用して簡略化でき、結果の Bean 名をメッセージングアノテーション adviceChain 属性で使用できます。

@Bean
public ConcurrentMetadataStore store() {
    return new SimpleMetadataStore(hazelcastInstance()
                       .getMap("idempotentReceiverMetadataStore"));
}

@Bean
public IdempotentReceiverInterceptor idempotentReceiverInterceptor() {
    return new IdempotentReceiverInterceptor(
            new MetadataStoreSelector(
                    message -> message.getPayload().toString(),
                    message -> message.getPayload().toString().toUpperCase(), store()));
}

@Bean
public TransactionInterceptor transactionInterceptor() {
    return new TransactionInterceptorBuilder(true)
                .transactionManager(this.transactionManager)
                .isolation(Isolation.READ_COMMITTED)
                .propagation(Propagation.REQUIRES_NEW)
                .build();
}

@Bean
@org.springframework.integration.annotation.Transformer(inputChannel = "input",
         outputChannel = "output",
         adviceChain = { "idempotentReceiverInterceptor",
                 "transactionInterceptor" })
public Transformer transformer() {
    return message -> message;
}

TransactionInterceptorBuilder コンストラクターの true パラメーターに注意してください。通常の TransactionInterceptor ではなく、TransactionHandleMessageAdvice が作成されます。

Java DSL は、次の例に示すように、エンドポイント構成の .transactional() オプションを介して Advice をサポートします。

@Bean
public IntegrationFlow updatingGatewayFlow() {
    return f -> f
        .handle(Jpa.updatingGateway(this.entityManagerFactory),
                e -> e.transactional(true))
        .channel(c -> c.queue("persistResults"));
}