1

我正在使用不同的連接工廠來發送和接收消息,在部分提交問題中遇到了發送失敗的問題。 jms:message-driven-channel-adapter使用receiveConnectionFactory ro從隊列中接收消息。 jms:outbound-channel-adapter使用deliverConnectionFactory將消息發送到下游隊列。我們只有一個JmsTransactionManager,它使用配置爲session-transacted="true"receiveConnectionFactoryjms:outbound-channel-adapter如何從兩個不同的連接工廠加入Spring JMS事務?

<beans> 
    <bean id="transactionManager" 
     class="org.springframework.jms.connection.JmsTransactionManager"> 
     <property name="connectionFactory" ref="receiveConnectionFactory" /> 
    </bean> 
    <bean id="receiveConnectionFactory" 
     class="org.springframework.jms.connection.CachingConnectionFactory"> 
     <property name="targetConnectionFactory"> 
      <bean class="com.ibm.mq.jms.MQQueueConnectionFactory"> 
       <property name="hostName" value="${mq.host}" /> 
       <property name="channel" value="${mq.channel}" /> 
       <property name="port" value="${mq.port}" /> 
      </bean> 
     </property> 
     <property name="sessionCacheSize" value="${receive.factory.cachesize}" /> 
     <property name="cacheProducers" value="${receive.cache.producers.enabled}" /> 
     <property name="cacheConsumers" value="${receive.cache.consumers.enabled}" /> 
    </bean> 

    <bean id="deliverConnectionFactory" 
     class="org.springframework.jms.connection.CachingConnectionFactory"> 
     <property name="targetConnectionFactory"> 
      <bean class="com.ibm.mq.jms.MQQueueConnectionFactory"> 
       <property name="hostName" value="${mq.host}" /> 
       <property name="channel" value="${mq.channel}" /> 
       <property name="port" value="${mq.port}" /> 
      </bean> 
     </property> 
     <property name="sessionCacheSize" value="${send.factory.cachesize}" /> 
     <property name="cacheProducers" value="${send.cache.producers.enabled}" /> 
     <property name="cacheConsumers" value="${send.cache.consumers.enabled}" /> 
    </bean> 

    <tx:advice id="txAdviceNew" transaction-manager="transactionManager"> 
     <tx:attributes> 
      <tx:method name="send" propagation="REQUIRES_NEW" /> 
     </tx:attributes> 
    </tx:advice> 

    <aop:config> 
     <aop:advisor advice-ref="txAdviceNew" pointcut="bean(inputChannel)" /> 
     <aop:advisor advice-ref="txAdviceNew" pointcut="bean(errorChannel)" /> 
    </aop:config> 

    <jms:message-driven-channel-adapter 
     id="mdchanneladapter" channel="inputChannel" task-executor="myTaskExecutor" 
     connection-factory="receiveConnectionFactory" destination="inputQueue" 
     error-channel="errorChannel" concurrent-consumers="${num.consumers}" 
     max-concurrent-consumers="${max.num.consumers}" max-messages-per-task="${max.messagesPerTask}" 
     transaction-manager="transactionManager" /> 

    <jms:outbound-channel-adapter 
     connection-factory="deliverConnectionFactory" session-transacted="true" 
     destination-expression="headers.get('Deliver')" explicit-qos-enabled="true" /> 
</beans> 

當任何一個目標存在MQ異常時,發生部分提交,然後發生失敗隊列提交。我正在查看是否缺少一些配置來加入事務,以便部分提交不會發生。

我試着只有一個連接工廠發送和接收(receiveConnectionFactory)和parital commit沒有發生,一切都按預期工作。

回答

2

我試着只有一個連接工廠發送和接收(receiveConnectionFactory)和parital commit沒有發生,一切都按預期工作。

這是正確的方式去你的情況。

我看到你的兩個ConnectionFactories只是他們的對象不同。其餘部分看起來像是同一個目標MQ服務器。

如果你絕對不能只用一個ConnectionFactory生活,你應該考慮使用JtaTransactionManager或兩個JmsTransactionManagers配置org.springframework.data.transaction.ChainedTransactionManager - 每個連接工廠之一。

見戴夫Syer對此事的文章:https://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

+0

感謝@Artem快速回復。是的,現在我們連接到同一個QManager進行接收和發送。我們正在爲將來實現不同的QManager進行發送和接收做準備。我會嘗試實現JtaTransactionManager或ChainedTransactionManager,看看是否解決了這個問題。 – Selvakumar

+1

更新 - 我添加了兩個JmsTransactionManagers - 每個連接工廠和ChainedTransactionManager加入事務。一切按預期工作,沒有部分提交。感謝@artem發佈解決方案。 – Selvakumar

相關問題