在进行事务处理时,消息未到达MSMQ

LCJ*_*LCJ 15 .net c# asp.net msmq

我在本地计算机上创建了一个私有MSMQ.我使用以下C#代码将消息发送到队列.当我将队列更改为事务时,消息未到达MSMQ.但是,Send方法中没有抛出异常.我需要做些什么改变才能让它发挥作用?

using System;
using System.Messaging;
using System.Data;

public partial class _Default : System.Web.UI.Page
{
    //Sharing violation resulted from queue being open already for exclusive receive.
    MessageQueue helpRequestQueue = new MessageQueue(@".\Private$\MyPrivateQueue", false);
    protected void Page_Load(object sender, EventArgs e)
    {   
        bool isTransactionalQueue = false;    
        if (!System.Messaging.MessageQueue.Exists(@".\Private$\MyPrivateQueue"))    
        {    
            System.Messaging.MessageQueue.Create(@".\Private$\MyPrivateQueue", isTransactionalQueue);    
        }    
        SendMessage();    
        GetAllMessages();    
    }


    private void SendMessage()    
    {    
        System.Messaging.Message theMessage = new System.Messaging.Message("TimeNow is "+DateTime.Now.ToString());

        theMessage.Label = "Lijo " + DateTime.Now.ToString();

        theMessage.Priority = System.Messaging.MessagePriority.Normal;

        helpRequestQueue.Send(theMessage);    

    }


    private void GetAllMessages()   
    {    
        DataTable messageTable = new DataTable();    
        messageTable.Columns.Add("Label");    
        messageTable.Columns.Add("Body");        


        //Set Message Filters    
        MessagePropertyFilter filter = new MessagePropertyFilter();    
        filter.ClearAll();    
        filter.Body = true;    
        filter.Label = true;    
        filter.Priority = true;
        helpRequestQueue.MessageReadPropertyFilter = filter;

        //Get All Messages    
        System.Messaging.Message[] messages = helpRequestQueue.GetAllMessages();    
        System.Messaging.XmlMessageFormatter stringFormatter = new System.Messaging.XmlMessageFormatter(new string[] { "System.String" });


        for (int index = 0; index < messages.Length; index++)    
        {    
            string test = System.Convert.ToString(messages[index].Priority);
            messages[index].Formatter = stringFormatter;    
            messageTable.Rows.Add(new string[] {messages[index].Label,messages[index].Body.ToString() });

        }


        Gridview1.DataSource = messageTable;    
        Gridview1.DataBind();    
    }    

    private void ReceiveAndProcess()    
    {



    }           
}
Run Code Online (Sandbox Code Playgroud)

Sai*_*Jin 22

对于已创建为transanctional的队列,必须使用包含MessageQueueTransactionType参数的Send()版本.最令人沮丧的是它不会像你看到的那样抛出任何异常或错误,但这些消息并没有出现.

所以,在你的代码中,改变:

helpRequestQueue.Send(theMessage); 
Run Code Online (Sandbox Code Playgroud)

helpRequestQueue.Send(theMessage, MessageQueueTransactionType.Single); 
Run Code Online (Sandbox Code Playgroud)

编辑:除了大卫之外,我的回答只是另一种方式.


小智 14

交易不起作用non-transactional queues.如果您使用此表单:

using(MessageQueueTransaction tx = new MessageQueueTransaction())
{
    tx.Begin();
    queue.Send(message, tx);
    tx.Commit();
}
Run Code Online (Sandbox Code Playgroud)

在非事务性队列上,消息似乎丢失,不会抛出任何异常.您可以在消息队列管理控制台中检查队列属性中的队列是否为事务性队列.

最好使用

queue.Send(message, MessageQueueTransactionType.Automatic)
Run Code Online (Sandbox Code Playgroud)


Dav*_*ter 7

根据MSDN,这是使用事务MSMQ队列的示例:

    // Connect to a transactional queue on the local computer.
    MessageQueue queue = new MessageQueue(".\\exampleTransQueue");

    // Create a new message.
    Message msg = new Message("Example Message Body");

    // Create a message queuing transaction.
    MessageQueueTransaction transaction = new MessageQueueTransaction();

    try
    {
        // Begin a transaction.
        transaction.Begin();

        // Send the message to the queue.
        queue.Send(msg, "Example Message Label", transaction);

        // Commit the transaction.
        transaction.Commit();
    }
    catch(System.Exception e)
    {
        // Cancel the transaction.
        transaction.Abort();

        // Propagate the exception.
        throw e;
    }
    finally
    {
        // Dispose of the transaction object.
        transaction.Dispose();
    }
Run Code Online (Sandbox Code Playgroud)

您必须将其视为数据库事务 - 通过创建新的MSMQ事务来开始事务,然后提交或中止操作.