0

I have used .net C# code to put messages on the queue and get messages back. I have no problem in accessing the queue and getting messages. Now I want to have the get message calls under Transaction and used explicit transaction option to commit and rollback the messages.

   try
        {
            MQQueueManager queueManager;

            MQEnvironment.Hostname = hostName;
            MQEnvironment.Channel = channelName;
            MQEnvironment.Port = 1414;
            MQEnvironment.properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);


            queueManager = new MQQueueManager(queueManagerName);


            // obtain a read/write queue reference
            var queue = queueManager.AccessQueue(queueName, MQC.MQOO_INPUT_AS_Q_DEF + MQC.MQOO_INQUIRE + MQC.MQOO_FAIL_IF_QUIESCING);
            IList<string> Messages = new List<string>();

            using (var scope = new CommittableTransaction())
            {
                CommittableTransaction.Current = scope; 
                var message = new MQMessage();

                try
                {
                    var getMessageOptions = new MQGetMessageOptions();
                   getMessageOptions.Options += MQC.MQGMO_SYNCPOINT ;
                    int i = queue.CurrentDepth;
                    queue.Get(message,getMessageOptions);                        
                    Console.WriteLine(message.ReadString(message.MessageLength));
                    scope.Rollback();
                }
                catch (MQException mqe)
                {
                    if (mqe.ReasonCode == 2033)
                    {
                        Console.WriteLine("No more message available");
                        Console.ReadLine();
                        scope.Rollback();
                    }
                    else
                    {
                        Console.WriteLine("MQException caught: {0} - {1}", mqe.ReasonCode, mqe.Message);
                        Console.ReadLine();
                        scope.Rollback();
                    }
                }
                CommittableTransaction.Current = null;
            }


            // closing queue

            queue.Close();


            // disconnecting queue manager

            queueManager.Disconnect();
            Console.ReadLine();

        }

        catch (MQException mqe)
        {
            Console.WriteLine("");
            Console.WriteLine("MQException caught: {0} - {1}", mqe.ReasonCode, mqe.Message);
            Console.WriteLine(mqe.StackTrace);
            Console.ReadLine();
        }

The first problem I faced was , related to access to System.Dotnet.XARecovery queue. Even though I had access to the queue to get messages from the queue , the program started to fail because of the access rights on the recovery queue when below line was invoked.

queue.Get(messages),

Then I got the access on the recovery queue and access denied problem was resolved. Now after getting the message from the queue , the messages are not roll backed after scope.RollBack() is called.

I checked in the System.Dotnet.XARecovery queue and dead letter queue and there was not nothing there as well.

Why I am not able to see the rolled back messages in the WMQ message queue.

Aman
  • 1
  • 3

2 Answers2

1

You have a scope.Commit(); after queue.Get(message); After getting the message you are explicitly calling the Commit. If the Get is successful, the Commit call tells the queue manager to remove the message from queue. So there is no chance of message getting rolled back.

EDIT: GMO_SYNCPOINT option is missing in your code. You need to have something like this

        MQGetMessageOptions getMessageOptions = new MQGetMessageOptions();
        getMessageOptions.Options += MQC.MQGMO_SYNCPOINT;
        queue.Get(message, getMessageOptions);
Shashi
  • 14,980
  • 2
  • 33
  • 52
  • Thanks Shashi for the response. I know if get is successfull scope gets committed. The problem is when the get has some error or when I call Rollback instead of commit . The messages are not rolled back on the queue. – Aman Oct 16 '13 at 08:19
  • I tried using the below mentioned options. MQGetMessageOptions getMessageOptions = new MQGetMessageOptions(); getMessageOptions.Options += MQC.MQGMO_SYNCPOINT; Except for the first time , rest all other times Queue.Get(message, getMessageOptions) cleared the message from the queue even after the transaction was rolledback. – Aman Oct 21 '13 at 10:34
  • Aman, a colleague of mine ran your code and he confirmed that the code works perfectly fine. Messages reappear after every Rollback. How are you checking that message not present in queue after Rollback is called? Are you checking the queue depth while debugging the code or your are checking after the program ends? – Shashi Oct 24 '13 at 17:26
  • I have tried checking the queue depth as well as looking in the websphere queue after the program ends.The queue depth just after the rollback does not show any sígns of rollback and neither does the WMQ queue explorer. I am now sure there is nothing extra I can do in my program to make it work for transation based WMQ access. I am not sure about the server WMQ server settings.Is there any guide or steps involved in setting up queues so that it enables transaktion based operations ? – Aman Oct 25 '13 at 11:46
  • I think it would be good idea to raise ticket with IBM to get this sorted out because we are not seeing the same problem as you are seeing. IBM service can analyze and determine what the problem is. – Shashi Oct 25 '13 at 15:15
0

I figured out the solution of my problem. In my code above if I change the line from

MQEnvironment.properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES);

to

MQEnvironment.properties.Add(MQC.TRANSPORT_PROPERTY, MQC.TRANSPORT_MQSERIES_MANAGED);

then it starts to register the transactions of the local DTC as well as it works fine in rolling back or commit a message on the queue.

Werner Henze
  • 16,404
  • 12
  • 44
  • 69
Aman
  • 1
  • 3