5

我的目标是使用 WebSphere MQ Java 编程将 n 条消息放在一个 for 循环中的 WebSphere MQ 队列中。

我的 java 程序将作为独立程序运行。

如果两者之间有任何异常,我需要回滚所有消息。

如果没有例外,那么我应该提交所有消息。

在我完全完成之前,外界不应该看到我在队列中的消息。我如何实现这一目标?

根据 T.Rob 的回复更新了示例代码:

请检查示例代码是否正常?

设置 MQGMO_SYNCPOINT 是否仅与我的程序调用有关?(因为并行运行的类似程序也会将消息放在同一个队列中,并且这些消息不应该受到我程序的 SYNCPOINT 的影响。)

public void sendMsg() {
        MQQueue queue = null;
        MQQueueManager queueManager = null;
        MQMessage mqMessage = null;
        MQPutMessageOptions pmo = null;
        System.out.println("Entering..");
        try {
            MQEnvironment.hostname = "x.x.x.x";
            MQEnvironment.channel = "xxx.SVRCONN";
            MQEnvironment.port = 9999;


            queueManager = new MQQueueManager("XXXQMANAGER");
            int openOptions = MQConstants.MQOO_OUTPUT;      
            queue = queueManager.accessQueue("XXX_QUEUENAME", openOptions, null, null, null);

            pmo = new MQPutMessageOptions(); 
            pmo.options = CMQC.MQGMO_SYNCPOINT;


            String input = "testing";
            System.out.println("sending messages....");
            for (int i = 0; i < 10; i++) {
                input = input + ": " + i;
                mqMessage = new MQMessage();
                mqMessage.writeString(input);
                System.out.println("Putting message: " + i);
                queue.put(mqMessage, pmo);

            }
            queueManager.commit();
            System.out.println("Exiting..");

        } catch (Exception e) {
            e.printStackTrace();
            try {
                System.out.println("rolling back messages");
                if (queueManager != null)
                    queueManager.backout();
            } catch (MQException e1) {
                e1.printStackTrace();
            }
        } finally {
            try {
                if (queue != null)
                    queue.close();
                if (queueManager != null)
                    queueManager.close();
            } catch (MQException e) {
                e.printStackTrace();
            }
        }
    }
4

3 回答 3

5

WMQ 支持本地和全局 (XA) 工作单元。只需指定选项即可使用本地工作单元。正如 keithkreissl 在另一个答案中提到的那样,全局 XA 事务需要事务管理器。

对于您所描述的,一个 POJO 在同步点下进行消息传递,MQC.MQGMO_SYNCPOINT请在您的MQGetMessageOptions. 当您准备好提交时,发出MQQManager.commit()orMQQManager.backout()调用。

请注意,ggrandes 提供的响应和文档是指 JMS 而不是 Java 类。Java 类使用 WMQ 过程 API 的 Java 等效项,可以支持许多线程 ( doc ),甚至提供连接池 ( doc )。请参阅 Java 文档而不是 JMS 文档以了解正确的行为。此外,我已链接到最新的WMQ Java V7.5 客户端附带的 WMQ V7.5 文档。后面的客户端有更多的本地功能(跟踪、灵活的安装路径、MQClient.ini 等)并与后级 QMgrs 一起使用。强烈建议使用最新的客户端,并且免费下载。

于 2013-01-20T21:59:48.110 回答
3

您只需要创建一个启用事务的会话。

Session session;
// ...
boolean transacted = true;
session = connection.createSession(transacted, Session.AUTO_ACKNOWLEDGE);
try {
    // ...do things...
    session.commit();
} catch (Exception e) {
    session.rollback();
}
// ...

警告注意:会话不是线程安全的 ;-)

于 2013-01-20T17:10:30.017 回答
1

如果您有权访问事务管理器,更重要的是连接到您的 MQ 访问的 XATransaction,您可以在消息处理开始时启动事务,将所有消息放在队列中,然后提交事务。使用 XATransactions 在事务提交之前它不会放置任何消息。如果您无权访问它,您可以通过将消息放在本地数据对象中进行更多检查,如果没有异常遍历发送消息的本地数据对象,则将代码包装在 try/catch 中。后一种方法的问题是它将提交您的所有其他处理,但如果在发送消息时出现问题,您的其他处理将不会回滚。

于 2013-01-20T16:42:29.470 回答