Search code examples
.netibm-mqxms

IBM XMS .NET - Receiving Error - Reason Code 2003


We have .NET application which reads from various queues using the XMS API. For this particular application we read from 3 queues and every so often receive the error with reason code 2003 on 2 of the 3 queues. All 3 of the queues are setup to have persistent messages.

From everything I have researched, it appears that a long running transaction being rolled back causing this error. The reason for the long running transaction being rolled back appears to be from exhausted log space. When the transaction gets rolled back, it puts the messages we have previously read onto the queue so we end up reading duplicates.

In the API, when we create our "Session" to read from the queues, we specify false for the transacted parameter. Therefore we never call "Commit" on the session. We also use the auto-acknowledge mode on the session. This leads me to believe that we don't have any sort of unit of work sepcified explicitly, but could there be an implicit transaction of some sort? The tricky part is that we are able to read fine on 1 of the 3 queues without ever receiving the error.

Any ideas on where I could look next to troubleshoot such an issue?

Creating the connection:

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); 

Creating the session:

MQConnection.CreateSession(false, AcknowledgeMode.AutoAcknowledge)

Creating the destination:

MQSession.CreateQueue(queueName)

Creating the consumer:

 MQSession.CreateConsumer(MQDestination)

Reading from the queue:

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

Solution

  • It turns out that there was an internal unit of work that was not being committed which would cause the messages to be rolled back on the queues upon a 2003 or 2024 failure. The solution to the problem was to set the flag on the MQ connection factory for WMQ_SYNCPOINT_ALL_GET to true. The default is false.

    Setting the flag:

    SetBooleanProperty(XMSC.WMQ_SYNCPOINT_ALL_GETS, true);