0

我使用 .net C# 代码将消息放入队列并取回消息。我在访问队列和获取消息方面没有问题。现在我想在事务下调用获取消息,并使用显式事务选项来提交和回滚消息。

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

我面临的第一个问题是,与访问System.Dotnet.XARecovery队列有关。即使我有权访问队列以从队列中获取消息,但由于调用以下行时恢复队列的访问权限,程序开始失败。

queue.Get(messages),

然后我获得了恢复队列的访问权限,访问被拒绝的问题得到了解决。scope.RollBack()现在从队列中获取消息后,消息在被调用后不会回滚。

我检查了System.Dotnet.XARecovery队列和死信队列,那里也没有任何东西。

为什么我无法在 WMQ 消息队列中看到回滚的消息。

4

2 回答 2

1

您有一个scope.Commit();afterqueue.Get(message);收到消息后,您明确地调用了 Commit。如果 Get 成功,则 Commit 调用告诉队列管理器从队列中删除消息。所以消息没有回滚的机会。

编辑:您的代码中缺少 GMO_SYNCPOINT 选项。你需要有这样的东西

        MQGetMessageOptions getMessageOptions = new MQGetMessageOptions();
        getMessageOptions.Options += MQC.MQGMO_SYNCPOINT;
        queue.Get(message, getMessageOptions);
于 2013-10-10T12:56:29.407 回答
0

我想出了我的问题的解决方案。在我上面的代码中,如果我将行从

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

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

然后它开始注册本地 DTC 的事务,并且在回滚或提交队列上的消息时工作正常。

于 2013-11-14T12:47:09.097 回答