Как мне использовать удаленную транзакцию MSMQ?
-
02-07-2019 - |
Вопрос
Я пишу службу Windows, которая извлекает сообщения из MSMQ и отправляет их в устаревшую систему (Baan).Если сообщение будет отправлено с ошибкой или компьютер выйдет из строя во время отправки, я не хочу потерять сообщение.Поэтому я использую транзакции MSMQ.Я прерываю работу при неудаче и обязуюсь добиться успеха.
При работе с локальной очередью этот код работает хорошо.Но в рабочей среде я захочу отделить машину (или машины), на которых запущена служба, от самой очереди.Когда я тестирую удаленную очередь, выдается исключение System.Messaging.MessageQueueException:"Использование транзакции недопустимо".
Я проверил, что рассматриваемая очередь является транзакционной.
Вот код, который получает из очереди:
// Begin a transaction.
_currentTransaction = new MessageQueueTransaction();
_currentTransaction.Begin();
Message message = queue.Receive(wait ? _queueTimeout : TimeSpan.Zero, _currentTransaction);
_logger.Info("Received a message on queue {0}: {1}.", queue.Path, message.Label);
WORK_ITEM item = (WORK_ITEM)message.Body;
return item;
Ответ
С тех пор я перешел на Брокер служб SQL.Он поддерживает удаленный транзакционный прием, в то время как MSMQ 3.0 этого не делает.И, в качестве дополнительного бонуса, он уже использует экземпляр SQL Server, который мы кластеризуем и создаем резервную копию.
Решение
Я оставил комментарий с вопросом о версии MSMQ, которую вы используете, поскольку я думаю, что это и есть причина вашей проблемы.Транзакционный прием не был реализован в более ранних версиях MSMQ.Если это так, то это запись в блоге объясняет ваши варианты.
Другие советы
Использование TransactionScope должно работать при условии, что MSDTC запущен на обеих машинах.
MessageQueue queue = new MessageQueue("myqueue");
using (TransactionScope tx = new TransactionScope()) {
Message message = queue.Receive(MessageQueueTransactionType.Automatic);
tx.Complete();
}
С тех пор я перешел на Брокер служб SQL.Он поддерживает удаленный транзакционный прием, в то время как MSMQ 3.0 этого не делает.И, в качестве дополнительного бонуса, он уже использует экземпляр SQL Server, который мы кластеризуем и создаем резервную копию.
Чтобы использовать область транзакции, вы должны предварительно убедиться, что установлен MSDTC и активировано подключение к удаленному клиенту.
Установка MSDTC не является проблемой, но активация удаленного клиентского подключения должна вызвать перезагрузку сервера (в Windows server 2003 это имеет место).
может быть, этот пост сможет вам помочь :Как активировать MSDTC и подключение к удаленному клиенту
Aviod с использованием удаленного MSMQ (иначе обновите до MSMQ 4.0 для поддержки удаленных транзакций MSMQ).1) В качестве альтернативы вы можете создать один веб-сервис для отправки сообщений 2) Создайте локальный MSMQ для целей транзакции 3) Создайте небольшую утилиту, которая имеет номер пакета и номера сообщений...Как только пакет завершится неудачно, удалите сообщения в target, иначе сделайте это областью действия транзакции