3

我正在编写一个在 LINUX 环境中运行的 Java 应用程序,它使用 SYNCPOINT 在 MQ 上执行事务。它使用 Websphere MQ Java 类与 MQ 服务进行交互。我在我的代码中所做的是以下(伪):

MQGetMessageOptions gmo = new MQGetMessageOptions();
gmo.options = MQConstants.MQGMO_FAIL_IF_QUIESCING | MQConstants.MQGMO_SYNCPOINT;

MQMessage message = new Message();
queue.get(message, gmo);

// process the message, save to database

databaseConnection.commit();
queueManager.commit();

我基本上抓取消息,处理它,持久化到数据库,然后在 queueManager 上调用提交。该进程在 TIBRV 上侦听消息以进行正常关闭。

我一直在测试该过程以确保没有消息丢失。我将 20k 条消息放在一个队列中,然后运行该过程。我在处理过程中执行了一个正常的关闭调用。然后,我将队列中的消息数量与数据库中的消息数量进行比较。当通过 TIBRV 消息正常关闭时,MQ 消息数 + DB 消息数 = 队列中最初的消息总数。

但是,当我执行killor时kill -9,我看到一条消息丢失了。我总是得到 19999 条消息的结果。

有没有办法可以调查我是如何丢失这条消息的?Websphere App Server 上是否发生了我需要注意的任何事情?

4

2 回答 2

5

在使用单阶段提交时,没有理由期望这些数字能够协调一致。当您杀死它时,该程序将始终位于 WMQ 和 DB Commit 调用之间,或者位于 DB 和 WMQ Commit 调用之间。

您所要求的将需要 2 阶段 (XA) 提交。对于 WMQ,2PC 将要求应用程序使用绑定模式并且 WMQ 是资源协调器。然后调用 MQBEGIN,执行 WMQ 和 DB 更新,然后调用 MQCOMMIT。这样,WMQ 和 DB 事务将一起成功或失败。

于 2011-04-29T18:33:20.503 回答
0

您是在绑定模式还是客户端模式下连接或 MQ?根据我的经验,事务在客户端模式下不能开箱即用,但在绑定模式下却可以。

于 2011-04-16T02:28:49.113 回答