2015-11-04 3 views
1

документация NServiceBus перечисляет преимущество SQL транспорта как:NServiceBus останавливает сообщение от двух пользователей?

Очереди поддержки конкурирующих потребителей (несколько экземпляров одного и того же конечной питаясь из той же очереди), так что нет необходимости дистрибьютора в целях расширения вне обработка

http://docs.particular.net/nservicebus/sqlserver/design

Кто NServiceBus предотвратить сообщение от быть обработаны несколькими потребителями, если несколько потребителей подписались на тот же дие у.е.?

Заблокирует ли NServiceBus всю таблицу до тех пор, пока сообщение не будет обработано? Или сообщение, помеченное как «обрабатывается»?

ответ

6

SQL Transport использует очень конкретные подсказки для блокировки, чтобы заблокировать строку и заставить другие конкурирующие потоки игнорировать любую заблокированную в настоящий момент строку.

NServiceBus.SqlServer 2.2.0 С (текущей версии на момент я пишу это) SQL используется, но переформатировать мной, это:

WITH message AS 
(
    SELECT TOP(1) * 
    FROM [{Schema}].[{Queue}] WITH (UPDLOCK, READPAST, ROWLOCK) 
    ORDER BY [RowVersion] ASC 
) 
DELETE FROM message 
OUTPUT deleted.Id, deleted.CorrelationId, deleted.ReplyToAddress, 
     deleted.Recoverable, deleted.Expires, deleted.Headers, deleted.Body; 

Он использует Common Table Expression для ограничения исходных данных к одной строке затем используйте следующие блокировочные подсказки:

  • UPDLOCK - Держите данные под замком с намерением его обновить.
  • READPAST - Игнорировать заблокированные строки и выбрать следующий разблокированный.
  • ROWLOCK - Зафиксируйте блокировки на уровне строк и не переходите на блокировки страниц или блокировки таблиц.

Выполняя всю вещь как удаление, но затем выводя данные, подлежащие удалению, мы можем прочитать данные, и если транзакция завершается, строка удаляется. В противном случае, если транзакция откатится, блокировка освобождается, и строка ожидает, что ее соберет следующий конкурирующий потребитель.