Transactions IBM MQ-消息读取和;调用离线事务服务

Transactions IBM MQ-消息读取和;调用离线事务服务,transactions,jms,ibm-mq,message-queue,spring-jms,Transactions,Jms,Ibm Mq,Message Queue,Spring Jms,我正在处理IBM MQ消息的消费者,我希望在阅读带有确认的消息后,使每条消息处理都是事务性的 一旦我从IBM MQ读取每条消息,我需要调用大约4到5个不同的rest服务。通过服务在不同的表中大约有1500-2000个插入 若任何服务因任何原因失败,我希望回滚处理该特定消息时发生的先前插入,并将消息留在队列中 我怎样才能达到同样的效果?我对IBM MQs/Jms非常陌生 我计划通过使用浏览信息来实现这一点 QueueBrowser queueBrowser = context.createBrow

我正在处理IBM MQ消息的消费者,我希望在阅读带有确认的消息后,使每条消息处理都是事务性的

一旦我从IBM MQ读取每条消息,我需要调用大约4到5个不同的rest服务。通过服务在不同的表中大约有1500-2000个插入

若任何服务因任何原因失败,我希望回滚处理该特定消息时发生的先前插入,并将消息留在队列中

我怎样才能达到同样的效果?我对IBM MQs/Jms非常陌生

我计划通过使用浏览信息来实现这一点

QueueBrowser queueBrowser = context.createBrowser(queue, "JMSCorrelationID='ID:c9d5e2d7c5c3e3c9d6d54040404040404040404040404040c9d5e2d7c5c3e3c9d6d54040404040404040404040404040'");

如果所有这些队列都位于同一个MQ队列管理器上,则应为此使用“本地JMS事务”。因此,创建IBM MQ JMS连接并使会话事务化(第一个参数设置为true):

注意:如果第一个参数为true,则忽略第二个参数

创建JMS队列和接收方,然后读取第一条消息,例如:

Message msg = msgConsumer.receive(100);
如果没有当前事务,则在收到的第一条消息上隐式启动MQ事务

接下来进行处理,如果一切顺利,则调用commit

如果没有,回滚事务,您将再次看到所有回滚消息。所以它可以像这样工作:

Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageConsumer msgConsumer = session.createConsumer(destination, null);
while( !isStopped() ) {

  try {

    Message msg = msgConsumer.receive(100);
    if( msg!=null ) { 
      ... call your REST services ...
      session.commit();
    }
    ... test for end condition ...
  }
  catch (Exception e) {
    ... error handling ...
    session.rollback();
  }
}

您建议的方法是每消息事务性的吗?这不会处理在后续REST调用失败时从以前的REST调用回滚插入。它只处理将消息回滚到队列。如果消息被重新传递,那么原始的REST调用将被重复,可能会在数据库中产生重复的记录。明白了。我需要哪些选项来实现我想要的功能?好吧,因为REST从定义上讲不是一个事务API,所以它不会内置。但是,如果您有机会使用JDBC而不是REST来访问数据库,您可以使用JTA和一个事务管理来结合JMS和JDBC事务。请参阅JMS的XAConnectionFactory和“JTA”
Session session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
MessageConsumer msgConsumer = session.createConsumer(destination, null);
while( !isStopped() ) {

  try {

    Message msg = msgConsumer.receive(100);
    if( msg!=null ) { 
      ... call your REST services ...
      session.commit();
    }
    ... test for end condition ...
  }
  catch (Exception e) {
    ... error handling ...
    session.rollback();
  }
}