2012-03-28 11 views
13

Mam prywatny MSMQ utworzony na moim komputerze lokalnym. Wysyłam wiadomości do kolejki, używając następującego kodu C#. Kiedy zmieniłem kolejkę na transakcyjną, wiadomość nie dociera do MSMQ. Jednak w metodzie wysyłania nie ma wyjątku. Jaką zmianę muszę wprowadzić, aby działała?Wiadomość nie dociera do MSMQ po dokonaniu transakcji

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



    }   
} 
+2

Domyślam się, że transakcja musi być zatwierdzona. http://msdn.microsoft.com/en-us/library/windows/desktop/ms701273(v=vs.85).aspx –

Odpowiedz

6

Per MSDN, oto przykład użycia transakcyjnej MSMQ kolejki:

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

trzeba traktować go jak transakcji DB - rozpocząć transakcję poprzez stworzenie nowej transakcji MSMQ, a następnie zatwierdzić lub przerwać operację.

2

Kolejka i typ wiadomości muszą być takie same - transakcyjne w tym przypadku. Jeśli nie otrzymasz wyjątku, użyj kodu negatywnego źródła w kodzie, aby znaleźć utracone wiadomości.

20

Dla kolejek, które zostały utworzone jako transanctional, należy użyć wersji Send(), która zawiera parametr MessageQueueTransactionType. Największą frustracją jest to, że nie wyjawia żadnych wyjątków ani błędów, ale wiadomość po prostu się nie pojawia.

Więc w kodzie, zmiany:

helpRequestQueue.Send(theMessage); 

do

helpRequestQueue.Send(theMessage, MessageQueueTransactionType.Single); 

EDIT: Moja odpowiedź jest po prostu inny sposób to zrobić oprócz Dawida.

13

Transakcje nie działają na non-transactional queues. Jeśli używasz tego formularza:

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

Na nietransakcyjnych kolejki, pojawi się komunikat, aby zostać utracone i nie zostanie wyrzucony wyjątek. Można sprawdzić, czy kolejka jest transakcyjna we właściwościach kolejki w konsoli zarządzania kolejkami wiadomości.

Lepiej używać

queue.Send(message, MessageQueueTransactionType.Automatic) 
Powiązane problemy