Транзакционные очереди

50

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

Транзакционные очереди должны применяться, когда необходимы следующие гарантии:

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

В следующем примере демонстрируется создание транзакционной очереди сообщений, а также отправка сообщения с использованием транзакции. Транзакционная очередь сообщений создается передачей true во втором параметре методу MessageQueue.Create():

using System;
using System.Messaging;

namespace MSMQSample
{
    class Program
    {
        static void Main(string[] args)
        {
            if (!MessageQueue.Exists(@".\MyTransactionalQueue"))
            {
                MessageQueue.Create(@".\MyTransactionalQueue", true);
            }

            var queue = new MessageQueue(@".\MyTransactionalQueue");
            var transaction = new MessageQueueTransaction();

            try
            {
                transaction.Begin();
                queue.Send("a", transaction);
                queue.Send("b", transaction);
                queue.Send("c", transaction);
                transaction.Commit();
            }
            catch
            {
                transaction.Abort();
            }
        }
    }
}

Если в очередь необходимо записывать сразу несколько сообщений в пределах одной транзакции, то для этого придется создать экземпляр объекта MessageQueueTransaction и вызвать его метод Begin(). По завершении отправки всех сообщений, относящихся к транзакции, следует вызвать метод Commit() того же объекта MessageQueueTransaction. Для отмены транзакции (не оставляя никаких сообщений в очереди) должен быть вызван метод Abort(), что и делается в блоке catch.

Пройди тесты
Лучший чат для C# программистов