简体   繁体   English

如何从两个不同的连接工厂加入Spring JMS事务?

[英]How to join Spring JMS transactions from two different connection factories?

I am using different connection factories for sending and receiving messages, having trouble with partial commit issues incase of delivey failures. 我正在使用不同的连接工厂来发送和接收消息,如果发生交付失败,则会遇到部分提交问题。 jms:message-driven-channel-adapter uses the receiveConnectionFactory ro receive the messages from the queue. jms:message-driven-channel-adapter使用receiveConnectionFactory ro接收来自队列的消息。 jms:outbound-channel-adapter uses the deliverConnectionFactory to send the messages multiple to downstream queues. jms:outbound-channel-adapter使用deliverConnectionFactory将消息多个发送到下游队列。 We have only one JmsTransactionManager which uses the receiveConnectionFactory and the jms:outbound-channel-adapter configured with session-transacted="true" . 我们只有一个JmsTransactionManager它使用receiveConnectionFactoryjms:outbound-channel-adapter与配置session-transacted="true"

<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>

When there is MQ exception on any one destination, the partial commit occurs and then the failure queue commit happens. 当任一目标上存在MQ异常时,将发生部分提交,然后发生故障队列提交。 I am looking to see if I am missing some configuration to join the transactions so that the partial commit never happens. 我正在寻找是否缺少一些配置来加入事务,以便永远不会发生部分提交。

I tried with only one connection factory for both send and receive ( receiveConnectionFactory ) and the parital commit is not happening, everything works as expected. 我只尝试了一个用于发送和接收的连接工厂( receiveConnectionFactory ),并且没有发生receiveConnectionFactory提交,所有操作都按预期进行。

I tried with only one connection factory for both send and receive ( receiveConnectionFactory ) and the parital commit is not happening, everything works as expected. 我只尝试了一个用于发送和接收的连接工厂( receiveConnectionFactory ),并且没有发生receiveConnectionFactory提交,所有操作都按预期进行。

That's the right way to go in your case. 这是适合您情况的正确方法。

I see that your two ConnectionFactories are only different by their objects. 我看到您的两个ConnectionFactories仅在对象方面有所不同。 Everything rest looks like the same target MQ server. 其余的一切看起来都像同一台目标MQ服务器。

If you definitely can't live with only one ConnectionFactory , you should consider to use JtaTransactionManager or configure org.springframework.data.transaction.ChainedTransactionManager for two JmsTransactionManagers - one per connection factory. 如果您绝对不能只使用一个ConnectionFactory ,则应考虑使用JtaTransactionManager或为两个JmsTransactionManagers配置org.springframework.data.transaction.ChainedTransactionManager每个连接工厂一个。

See Dave Syer's article on the matter: https://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html 请参阅Dave Syer关于此事的文章: https : //www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with-and-without-xa.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM