NServiceBus 阻止消息被两个消费者处理?

NServiceBus stops a message from being handled by two consumers?

NServiceBus 文档列出了 SQL 传输的好处:

Queues support competing consumers (multiple instances of same endpoint feeding off of same queue) so there is no need for distributor in order to scale out the processing

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

如果多个消费者订阅了同一个队列,NServiceBus 会阻止谁来阻止消息被多个消费者处理?

NServiceBus 是否锁定整个 table 直到消息被处理?或者邮件标记为 'being processed' ??

SQL 传输使用非常具体的锁定提示来锁定行并导致其他竞争线程忽略当前锁定的任何行。

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将源数据限制为一行到return,然后使用以下锁提示:

  • UPDLOCK - 锁定数据以更新它。
  • READPAST - 忽略锁定的行并获取下一个未锁定的行。
  • ROWLOCK - 强制行级锁,不要升级到页锁或 table 锁。

通过将整个操作作为删除执行,然后输出要删除的数据,我们可以读取数据,如果事务提交,则删除该行。否则,如果事务回滚,则释放锁并等待下一个竞争消费者拾取该行。