Подтвердить что ты не робот

Сообщение не достигает MSMQ при совершении транзакционного

У меня есть собственный MSMQ, созданный на моей локальной машине. Я отправляю сообщения в очередь, используя следующий код С#. Когда я изменил очередь на транзакцию, сообщение не доходит до MSMQ. Однако в методе отправки исключений нет. Какие изменения мне необходимо внести, чтобы заставить его работать?

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()    
    {



    }           
}
4b9b3361

Ответ 1

Для очереди, которую вы создали как трансантракт, вы должны использовать версию Send(), которая включает параметр MessageQueueTransactionType. Самое большое разочарование в том, что он не бросает никаких исключений или ошибок, как вы видели, но сообщение просто не появляется.

Итак, в вашем коде измените:

helpRequestQueue.Send(theMessage); 

к

helpRequestQueue.Send(theMessage, MessageQueueTransactionType.Single); 

Изменить: Мой ответ - это еще один способ сделать это в стороне от Дэвида.

Ответ 2

Сделки не работают на non-transactional queues. Если вы используете эту форму:

using(MessageQueueTransaction tx = new MessageQueueTransaction())
{
    tx.Begin();
    queue.Send(message, tx);
    tx.Commit();
}

В очереди без транзакции сообщение оказывается потерянным, и никакое исключение не будет выбрано. Вы можете проверить, является ли транзакция транзакцией в свойствах для очереди в консоли управления Message Queuing.

Лучше использовать

queue.Send(message, MessageQueueTransactionType.Automatic)

Ответ 3

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

Вы должны рассматривать это как транзакцию БД - начать транзакцию, создав новую транзакцию MSMQ, а затем либо зафиксировать, либо прервать операцию.

Ответ 4

Очередь и тип сообщения должны быть одинаковыми - транзакционные в этом случае. Если вы не получите исключение, используйте "Negative Source Journaling" в вашем коде, чтобы помочь найти потерянные сообщения.