How to view MQ Websphere message without deleting it?

I am writing a .NET Windows Forms application that sends a message to the WebSphere MQ queue and then polls another queue for a response. If the response is returned, the application will partially process the response in real time. But the answer must remain in the queue, so that the daily batch job, which is also read from the response queue, can do the rest of the processing.

I read the message. What I could not understand was to read it without deleting it.

Here is what I have so far. I am new to MQ, so any suggestions would be appreciated. And feel free to answer in C #.

Public Function GetMessage(ByVal msgID As String) As MQMessage Dim q = ConnectToResponseQueue() Dim msg As New MQMessage() Dim getOpts As New MQGetMessageOptions() Dim runThru = Now.AddMilliseconds(CInt(ConfigurationManager.AppSettings("responseTimeoutMS"))) System.Threading.Thread.Sleep(1000) 'Wait for one second before checking for the first response' While True Try q.Get(msg, getOpts) Return msg Catch ex As MQException When ex.Reason = MQC.MQRC_NO_MSG_AVAILABLE If Now > runThru Then Throw ex System.Threading.Thread.Sleep(3000) Finally q.Close() End Try End While Return Nothing 'Should never reach here' End Function 

NOTE. I have not yet confirmed that my code really deletes the message. But this is how I understand that MQ works, and it looks like what's going on. Please correct me if this is not the default behavior.

+7
message-queue ibm-mq
source share
4 answers

You need to open a queue with the MQOO_BROWSE parameter. Then, on first reading, you do a GET using the MQGMO_BROWSE_FIRST option. Finally, your next GET should use the MQGMO_BROWSE_NEXT parameter.

Note: MQOO are the open MQ options, and MQGMO are the options for receiving MQ messages.

+11
source share

You really have to do this with separate queues. End-of-day processing should have a turn. After processing your part of the message, you send it to the EOD queue.

Using the "Browse" option, you will need to keep track of which messages you have already processed.

In addition, you can set the wait timeout in GET. Therefore, you do not need to "wait 1 second before checking the queue." As it is written right now, you cannot press the msg absence condition because you did not set NOWAIT in the message receiving options.

+1
source share

For posterity, here (I think) a significantly improved version of the method based on the answers to mamboking and jmucchiello.

 Public Function GetMessage(ByVal correlID As Byte()) As MQMessage Dim waitInterval = CInt(ConfigurationManager.AppSettings("responseTimeoutMS")) Dim q As MQQueue = Nothing Try Dim msg As New MQMessage() Dim getOpts As New MQGetMessageOptions() q = ConnectToResponseQueue() msg.MessageId = MQC.MQMI_NONE msg.CorrelationId = correlID getOpts.MatchOptions = MQC.MQMO_MATCH_CORREL_ID getOpts.WaitInterval = waitInterval getOpts.Options = MQC.MQGMO_BROWSE_FIRST Or MQC.MQGMO_WAIT q.Get(msg, getOpts) Return msg Finally If q IsNot Nothing AndAlso q.IsOpen() Then q.Close() End Try End Function 
+1
source share

I understand that I come to this discussion a bit late, and you probably already encoded this application. In case you ever need to change it or for someone else who might need something like that, I have a few observations.

Firstly, if you can do this with the v7 QMgr and v7 WMQ client, this would be the preferred solution. In version 7, .Net support was moved from SupportPac to part of the base product. There is significant new functionality, some bug fixes and better performance. Alternatively, on v7 you can use pub-sub ..., which brings me to the second observation.

Based on the description in the original post, I would do it in Pub-Sub. An application that posts a message requires only one, and it does not even need to know what it puts in the subject. In fact, you can create an alias for a topic that makes it look like a message producer queue. Your consumer applications can either subscribe, or you can do two administrative subscriptions so that the published messages move into the two queues that you have assigned. Then your applications have a dedicated queue, and for the producer and the packaged application there are no changes in the encoding, it's just a setting. Of course, a transaction management application should actually consume messages, not view them.

There are several advantages:

  • When the queue is filled with messages, indexing is flushed to disk, and over the threshold you will see a performance hit, which can be significant. Therefore, the current method does not scale all this well.
  • In the pub-sub method, you can have multiple instances of real-time or batch applications, or both, and they can be the same or different QMgr. Scaling is very simple.
  • You eliminate the dependency between real-time applications and the package, which should be in the same QMgr.
  • More transparent administration. If you see messages generated in the queue in real time, you know that you have a problem.

Here are a couple of completely different problems. One of them is to use the Fail Failure option. The purpose of this is that when QMgr shuts off cleanly, this parameter causes your API call to end with a return code indicating that QMgr is shutting down. If you do not enable this option, then it is possible that with two or more connected applications, QMgr will never turn off and will not be forced off or its processes will be destroyed by brute force. As a rule of thumb, always use Fail if Quiescing for all API calls that support it. The reason it exists is people who need a transactional XA transaction, but for some reason cannot use it. In this case, CONNECT and the first GET or PUT call use Fail if the Quiescing parameter and subsequent GET or PUT operations are not performed. This causes QMgr to wait for the complete set of GET / PUT calls to complete, but then the next CONNECT or GET / PUT will use Fail if Quiescing, so QMgr has the option to disconnect if necessary.

Another note here is that there is no Catch code here. I guess there is another scale in the call stack? It is always advisable to print the WMQ return code from the exception so that you can track the root cause. For consulting purposes, I always advise clients that a failure to print a return code (or a related exception for a JMS / XMS code) is a showstopper that should prevent the application from being promoted to Production. It really is that important. Even if you have a catch in the code that calls getMessage (), someone reusing a snippet of sample code might not realize that this important part is missing.

+1
source share

All Articles