We need to transfer messages between a RabbitMQ and MQSeries.
For this we use the configuration below.
<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>
We want to acknowledge the message in the RabbitMQ queue that in case the writing in MQSeries is good. For this we use the attribute channel-transacted
on the amqp inbound and session-transacted
on the jms outbound.
Is this the right way to do it?
How can we test the scenario where the message is well written in the MQSeries Queue (blue arrow) but an error occurs during the confirmation to RabbitMQ (green arrow)? Is it possible then to rollback on MQSeries? and retry with this message from RabbitMQ.
Thanks for your help.
No; that is not possible; RabbitMQ cannot participate in a Global (JTA) transaction.
You will get a duplicate publish to MQ and will need to deal with it on the JMS consumer side.
You don't really need channel-transacted
for this scenario; RabbitMQ transactions are mainly about publishing messages to RabbitMQ.
Consumption of messages is not transactional, but sending the ack
is done in the transaction and can be rolled back.
Non-transactional consumption in this use case will provide the same semantics as transactional.
You can read about the limitation of RabbitMQ transactions here.