【问题标题】:IBM MQ - Message reading & invoking down-line services transactionalIBM MQ - 消息读取和调用下线服务事务
【发布时间】:2019-10-16 08:08:57
【问题描述】:

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

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

如果任何服务因任何原因失败,我想回滚之前在处理该特定消息时发生的插入并将消息留在队列中。

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

我打算通过使用浏览消息来做到这一点

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

【问题讨论】:

    标签: transactions jms ibm-mq message-queue spring-jms


    【解决方案1】:

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

    session = connection.createSession(true, Session.AUTO_ACKNOWLEDGE);
    

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

    创建您的 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'
    猜你喜欢
    • 2013-01-02
    • 1970-01-01
    • 1970-01-01
    • 2018-09-16
    • 2022-07-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多