Сообщение не достигает 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()
{
}
}
Ответы
Ответ 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" в вашем коде, чтобы помочь найти потерянные сообщения.