Глобальная транзакция между входящим AMQP и исходящим JMS

Нам нужно передавать сообщения между 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 исправна. Для этого мы используем атрибут channel-transacted для входящего amqp и session-transacted для исходящего jms.

Это правильный способ сделать это?

Как мы можем протестировать сценарий, когда сообщение хорошо написано в очереди MQSeries (синяя стрелка), но при подтверждении RabbitMQ возникает ошибка (зеленая стрелка)? Возможен ли тогда откат на MQSeries? и повторите попытку с этим сообщением от RabbitMQ.

Спасибо за вашу помощь.


person Eric NICOLAS    schedule 11.03.2020    source источник


Ответы (1)


Нет; это невозможно; RabbitMQ не может участвовать в глобальной (JTA) транзакции.

Вы получите дубликат публикации в MQ, и вам нужно будет обработать его на стороне потребителя JMS.

Вам действительно не нужен channel-transacted для этого сценария; Транзакции RabbitMQ в основном связаны с публикацией сообщений в RabbitMQ.

Получение сообщений не является транзакционным, но отправка ack выполняется в транзакции и может быть отменена.

Нетранзакционное потребление в этом варианте использования будет обеспечивать ту же семантику, что и транзакционное.

Вы можете прочитать об ограничении транзакций RabbitMQ здесь.

person Gary Russell    schedule 11.03.2020
comment
Мне это не очень понятно. В int-amqp:inbound-channel-adapter acknowledge-mode не установлено (по умолчанию AUTO), когда подтверждено сообщение RabbitMQ? Канал получит это сообщение (зеленая стрелка) и опубликует его в MQ (оранжевая стрелка), а затем подтвердит его в RabbitMQ? это тот же поток, который обрабатывает чтение в amqp и запись в jms? а затем отправить подтверждение после завершения записи? - person Eric NICOLAS; 11.03.2020
comment
Да; с использованием прямого канала (по умолчанию) публикация JMS происходит в потоке-потребителе AMQP, а подтверждение отправляется, когда поток возвращается в контейнер прослушивателя. - person Gary Russell; 11.03.2020
comment
Спасибо за возвращение, понятно! С определением int-jms: outbound-channel-adapter, если ошибка возникает после записи в MQ и до возврата к каналу (оранжевая стрелка), произойдет откат (удаление сообщения в MQ), потому что мы используем session-transacted? И канал повторит попытку позже с сообщением, не подтвержденным от Rabbit? - person Eric NICOLAS; 11.03.2020
comment
Правильно, но не позже, почти сразу (но это зависит от предварительной выборки, будет ли неудавшаяся запись доставлена ​​повторно или она будет доставлена ​​повторно после предварительно выбранных сообщений). - person Gary Russell; 11.03.2020