Eu sou um DBA, então isso tempera minha resposta, mas aqui está o que eu faria:
- Se você estiver usando o SQL 2005+, use o Service Broker para armazenar as mensagens no banco de dados em vez de armazená-las em uma tabela. Você obtém um mecanismo de enfileiramento com isso, para poder se livrar do MSMQ. Você também terá uma tabela, mas ela apenas armazenará o identificador da conversa (essencialmente, um ponteiro para a mensagem) junto com quantas vezes ele tentou essa mensagem. Por fim, você desejará algum tipo de "caixa de mensagens mortas" para onde vão as mensagens que atingem seu limite de repetição.
- No seu código de processamento de mensagens, faça o seguinte:
- Iniciar uma transação
- Receba uma mensagem fora da fila
- Se a contagem de novas tentativas for maior que o limite, mova-a para a caixa de mensagens mortas e confirme
- Incremente o contador na mesa para esta mensagem
- Processar a mensagem
- Se o processamento for bem-sucedido, confirme a transação
- Se o processamento falhou, coloque uma nova mensagem na fila com o mesmo conteúdo e confirme a transação
Observe que não há reversões planejadas. Reversões no Service Broker podem ser ruins; se você reverter 5 vezes sem um recebimento bem-sucedido, a fila será desativada para enfileiramento e desenfileiramento. Mas você ainda quer ter transações para o caso em que seu processador de mensagens morre no meio do processamento (ou seja, o servidor trava).