2012-03-28 13 views
13

Tengo un MSMQ privado creado en mi máquina local. Estoy enviando mensajes a la cola usando el siguiente código de C#. Cuando cambié la cola para que fuera transaccional, el mensaje no llega al MSMQ. Sin embargo, no hay excepción lanzada en el método de envío. ¿Qué cambio necesito hacer para que funcione?El mensaje no llega a MSMQ cuando se realiza la transacción

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

Mi conjetura es que la transacción tiene que estar comprometido. http://msdn.microsoft.com/en-us/library/windows/desktop/ms701273(v=vs.85).aspx –

Respuesta

6

por MSDN, he aquí un ejemplo de la utilización de una cola transaccional de 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(); 
    } 

Tienes que tratarla como si fuera una transacción DB - iniciar la transacción mediante la creación de la nueva transacción MSMQ, y luego confirmar o abortar la operación.

2

La cola y el tipo de mensaje deben ser los mismos: transaccionales en este caso. Si no obtiene una excepción, utilice el Registro de origen negativo en su código para ayudar a encontrar los mensajes perdidos.

20

Para las colas que ha creado como transanccionales, debe usar la versión de Send() que incluye el parámetro MessageQueueTransactionType. La mayor frustración con esto es que no arroja ninguna excepción o error como ha visto, pero el mensaje simplemente no aparece.

Por lo tanto, en el código, cambie:

helpRequestQueue.Send(theMessage); 

a

helpRequestQueue.Send(theMessage, MessageQueueTransactionType.Single); 

Editar: Mi respuesta es simplemente otra manera de hacerlo, aparte de la de David.

13

Las transacciones no funcionan en non-transactional queues. Si utiliza este formulario:

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

en una cola no transaccional, el mensaje parece estar perdida y será lanzada no es una excepción. Puede verificar si una cola es transaccional en las propiedades de la cola en la consola de administración de Message Queue Server.

Es mejor utilizar

queue.Send(message, MessageQueueTransactionType.Automatic) 
Cuestiones relacionadas