2

我们有 .NET 应用程序,它使用 XMS API 从各种队列中读取数据。对于这个特定的应用程序,我们从 3 个队列中读取数据,并且每隔一段时间就会在 3 个队列中的 2 个队列上收到带有原因代码 2003 的错误。所有 3 个队列都设置为具有持久消息。

从我研究的所有内容来看,似乎是一个长时间运行的事务被回滚导致了这个错误。长时间运行的事务被回滚的原因似乎是日志空间耗尽。当事务回滚时,它会将我们之前读取的消息放入队列中,因此我们最终会读取重复的消息。

在 API 中,当我们创建“会话”以从队列中读取数据时,我们为 transacted 参数指定 false。因此,我们从不在会话中调用“提交”。我们还在会话上使用自动确认模式。这使我相信我们没有明确指定任何类型的工作单元,但是是否存在某种隐式事务?棘手的部分是我们能够在 3 个队列中的 1 个队列上正常读取,而不会收到错误。

关于我可以在哪里解决此类问题的任何想法?

创建连接:

cf.SetStringProperty(XMSC.WMQ_HOST_NAME, hostName);
cf.SetIntProperty(XMSC.WMQ_PORT, port);
cf.SetStringProperty(XMSC.WMQ_CHANNEL, channelName);
cf.SetIntProperty(XMSC.WMQ_CONNECTION_MODE, XMSC.WMQ_CM_CLIENT_UNMANAGED);
cf.SetStringProperty(XMSC.WMQ_QUEUE_MANAGER, managerName);
cf.SetStringProperty(XMSC.WMQ_SSL_KEY_REPOSITORY, EncryptionSettings.SSLRepositoryPath);
cf.SetStringProperty(XMSC.WMQ_SSL_CIPHER_SPEC, EncryptionSettings.CipherType);
cf.SetIntProperty(XMSC.WMQ_FAIL_IF_QUIESCE, XMSC.WMQ_FIQ_YES); 

创建会话:

MQConnection.CreateSession(false, AcknowledgeMode.AutoAcknowledge)

创建目的地:

MQSession.CreateQueue(queueName)

创建消费者:

 MQSession.CreateConsumer(MQDestination)

从队列中读取:

var rawMessage = messageConsumer.Receive((long)TimeSpan.FromSeconds(15).TotalMilliseconds);
4

2 回答 2

1

事实证明,有一个内部工作单元未提交,这将导致消息在 2003 或 2024 故障时回滚到队列中。该问题的解决方案是将 MQ 连接工厂上的 WMQ_SYNCPOINT_ALL_GET 标志设置为 true。默认值为假。

设置标志:

SetBooleanProperty(XMSC.WMQ_SYNCPOINT_ALL_GETS, true);
于 2013-12-09T14:06:36.930 回答
0

XMS .NET 在本地事务下读取持久消息,因为会话被创建为非事务性和自动确认。这是为了避免在向应用程序传递消息期间丢失任何消息。因此,XMS .NET 在内部调用 Commit 来告诉队列管理器从队列中删除消息。

你的代码很简单,我看不出问题。

任何队列中是否有任何格式错误的消息?具有 XMS 不理解的标头的消息将在达到回退阈值 (BOTHRESH) 后回退到回退 (BOQUEUE) 队列。

您是否为读取消息的队列定义了回退队列或死信队列?消息是否堆积在回退队列中?

最后我建议向 IBM 提出 PMR 来解决这个问题。

于 2013-12-07T03:23:08.207 回答