4
votes

Are the features below supported by IBM Websphere MQ in .NET client? Please provide code example.

1. Publisher Confirms

When Publisher sends messages to queue, it receives confirmations from MQ server that messages have been saved to hard disk.

Does MQ server save message before sending confirmation?

Update 2

Is it corrent that when MQQueue.Put() returns, the message has been saved to transaction log? How long does it take to save to disk? What about message persistence in a cluster?

     void PutMessage(byte[] messageString)
    {
        try{

            // creating a message object
            message = new MQMessage();
            message.Write(messageString);
            message.Format = MQC.MQFMT_STRING;
            message.CharacterSet = 1208;// IbmUtf8Encoding;
            message.Persistence = MQC.MQPER_PERSISTENT;

            var options = new MQPutMessageOptions
            {
                Options = useSyncPoint ? MQC.MQPMO_SYNCPOINT : MQC.MQPMO_NO_SYNCPOINT
            };

            queue.Put(message, options);
            qMgr.Commit();

        }catch(Exception e){
            qMgr.Backout();
        }
    }

2. Consumer Acknowledgement

When Consumer receives messages from queue, processes them, then sends acknowledgement to MQ server.

Update 3

How can Consumer acknowledges to MQ server that messages have been processed successfully, and the messages can be safely deleted from server?

public void GetMessages()
    {            
        Open(ConnectionMode.Read);

        for (int i = 1; i <= numberOfMsgs; i++)
        {             
            GetMessage();
        }
        queue.Close();
        queueManager.Disconnect();         
    }

    public string GetMessage()
    {
        message = new MQMessage { Format = MQC.MQFMT_STRING };
        var mqMessageOptions = new MQGetMessageOptions
        {           
            Options = MQC.MQGMO_WAIT | MQC.MQGMO_FAIL_IF_QUIESCING | MQC.MQGMO_SYNCPOINT
        };

        queue.Get(message, mqMessageOptions, MaxMessageSizeInBytes);

        var content = message.ReadString(message.MessageLength);
        message.ClearMessage();

        return content;
    }


public void Open(ConnectionMode websphereConnectionMode)
    {
        var connectionSettings = new Hashtable
        {
            {MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED },
            {MQC.CONNECT_OPTIONS_PROPERTY, MQC.MQCNO_RECONNECT }
        };

        int openOptions = 0;

        switch (websphereConnectionMode)
        {
            case ConnectionMode.Read:
                openOptions = MQC.MQOO_INPUT_SHARED + MQC.MQOO_FAIL_IF_QUIESCING;
                break;
            case ConnectionMode.Write:
                openOptions = MQC.MQOO_OUTPUT + MQC.MQOO_FAIL_IF_QUIESCING;
                break;
        }
        queueManager = new MQQueueManager(queueManagerName);
        queue = queueManager.AccessQueue(queueName, openOptions);
    }


    public enum ConnectionMode
    {
        Read,
        Write
    }

How to do an explicit ACK when receiving Websphere MQ messages?

2
You would need to commit for it to be finalized, when the commit returns it would have been written to disk. Messages stay persistent for the life of the message, so when hopping to other queue managers via classic or cluster channels it will be persisted to disk along the way.JoshMc
Can you be more specific?Pingpong
I would suggest you download MQ Advanced for Developers and try this stuff out yourself. You have already modified your question to encompass what should have three different questions. The original question as asked by you was answered by @AttilaRepasi.JoshMc
You then modified it to ask a second more specific question which @Roger answered. Now you have modified it to ask a third question, each of those should have been different questions, Stackoverflow is supposed to be one question/answer per post.JoshMc
I did NOT change my original questions. There are questions related to question 1, for example it includes cluster, which needs clarifying. If it is easily answered, it would have been answered. These are valuable questions which are helpful for other readers.Pingpong

2 Answers

2
votes
  1. If the message is persistent, then MQ will write it into the transaction log and wait for the log extent to reach the disk, before put returns.

  2. To achieve this, the consumer should read messages under syncpoint, and commit the gets after appropriate processing is done on the client side.

1
votes

Your updated code is correct so far but you are missing either MQ commit or backout. Your code needs to tell MQ that the UOW (Unit of Work) is complete or to undue it. i.e.

qMgr.Commit();

or

qMgr.Backout();