Aman
Aman

Reputation: 11

WMQ Transactions Rollback using .net explicit Transactions not working

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.

Upvotes: 0

Views: 1545

Answers (2)

Aman
Aman

Reputation: 11

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.

Upvotes: 1

Shashi
Shashi

Reputation: 15273

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

Upvotes: 2

Related Questions