AMQP Inbound 和 JMS Outbound 之间的全局事务

Global transaction between AMQP Inbound and JMS Outbound

我们需要在 RabbitMQ 和 MQSeries 之间传输消息。

为此,我们使用以下配置。


<int:channel id="channelRmqMQ"></int:channel>

<int-amqp:inbound-channel-adapter   channel="channelRmqMQ" 
                                    queue-names=" QUEUE_OUT " 
                                    connection-factory="rabbitConnectionFactory" 
                                    auto-startup="true" 
                                    id="inboundChannelAdapter" 
                                    channel-transacted="true" 
                                    concurrent-consumers= " 1" 
                                    prefetch-count="40" 
                                    tx-size="40"
/>

<int-jms:outbound-channel-adapter   channel="channelRmqMQ" 
                                    id="jmsOut" 
                                    destination="jmsQueue" 
                                    connection-factory="connectionFactoryCaching" 
                                    delivery-persistent="true" 
                                    explicit-qos-enabled="true" 
                                    session-transacted="true" >
    <int-jms:request-handler-advice-chain>
        <ref bean="requestHandler" />
    </int-jms:request-handler-advice-chain>
</int-jms:outbound-channel-adapter>


我们想确认 RabbitMQ 队列中的消息,以防万一 MQSeries 中的写入是好的。为此,我们在 amqp 入站上使用属性 channel-transacted,在 jms 出站上使用 session-transacted

这样做正确吗?

如何测试消息在MQSeries Queue(蓝色箭头)中写入良好但在向RabbitMQ(绿色箭头)确认时发生错误的场景?是否可以在 MQSeries 上回滚?并使用来自 RabbitMQ 的消息重试。

感谢您的帮助。

否;这是不可能的; RabbitMQ 无法参与全局 (JTA) 事务。

您将重复发布到 MQ,需要在 JMS 消费者端处理它。

对于这种情况,您真的不需要 channel-transacted; RabbitMQ事务主要是发布消息到RabbitMQ。

消息的消费不是事务性的,但发送 ack 是在事务中完成的,可以回滚。

此用例中的非事务性消费将提供与事务性消费相同的语义。

您可以阅读 RabbitMQ 事务的限制 here