Partilhar via


Visão geral do processamento de transações do Service Bus

Este artigo discute os recursos de transação do Microsoft Azure Service Bus. Grande parte da discussão é ilustrada pela amostra de transações. Este artigo é limitado a uma visão geral do processamento de transações e do recurso enviar via no Service Bus, enquanto o exemplo de Transações Atômicas é mais amplo e complexo em escopo.

Nota

  • A camada básica do Service Bus não oferece suporte a transações. Os níveis padrão e premium suportam transações. Para conhecer as diferenças entre esses níveis, consulte Preços do Service Bus.
  • Não há suporte para a mistura de operações de gerenciamento e mensagens em uma transação.
  • O JavaScript SDK não suporta transações.

Transações no Service Bus

Uma transação agrupa duas ou mais operações em um escopo de execução. Por natureza, essa operação deve assegurar que todas as operações pertencentes a um determinado grupo de operações sejam bem sucedidas ou fracassem conjuntamente. A este respeito, as transações funcionam como uma unidade, o que é frequentemente referido como atomicidade.

O Service Bus é um agente de mensagens transacionais e garante a integridade transacional de todas as operações internas em relação aos seus armazenamentos de mensagens. Todas as transferências de mensagens no Service Bus, como mover mensagens para uma fila de mensagens mortas ou encaminhamento automático de mensagens entre entidades, são transacionais. Como tal, se o Service Bus aceitar uma mensagem, ela já foi armazenada e rotulada com um número de sequência. A partir de então, todas as transferências de mensagens dentro do Service Bus são operações coordenadas entre entidades e não levarão à perda (a origem é bem-sucedida e o destino falha) nem à duplicação (a origem falha e o destino é bem-sucedido) da mensagem.

O Service Bus suporta operações de agrupamento em relação a uma entidade de mensagens única (fila, tópico, subscrição) no âmbito de uma transação. Por exemplo, você pode enviar várias mensagens para uma fila de dentro de um escopo de transação, e as mensagens só serão confirmadas no log da fila quando a transação for concluída com êxito.

Operações dentro de um escopo de transação

As operações que podem ser executadas dentro de um escopo de transação são as seguintes:

  • Enviar
  • Concluído
  • Abandonar
  • Carta morta
  • Adiar
  • Renovar cadeado

As operações de recebimento não estão incluídas, porque supõe-se que o aplicativo adquire mensagens usando o modo peek-lock, dentro de algum loop de recebimento ou com um retorno de chamada, e só então abre um escopo de transação para processar a mensagem.

A disposição da mensagem (completar, abandonar, letra morta, adiar) ocorre então dentro do escopo e dependendo do resultado geral da transação.

Importante

O Barramento de Serviço do Azure não tenta novamente uma operação em caso de exceção quando a operação está em um escopo de transação.

Operações que não se alistam em escopos de transação

Lembre-se de que o código de processamento de mensagens que chama bancos de dados e outros serviços, como o Cosmos DB, não alista automaticamente esses recursos downstream no mesmo escopo transacional. Para obter mais informações sobre como lidar com esses cenários, consulte as diretrizes sobre processamento idempotente de mensagens.

Transferências e "enviar via"

Para habilitar a transferência transacional de dados de uma fila ou tópico para um processador e, em seguida, para outra fila ou tópico, o Service Bus oferece suporte a transferências. Em uma operação de transferência, um remetente primeiro envia uma mensagem para uma fila ou tópico de transferência, e a fila ou tópico de transferência move imediatamente a mensagem para a fila ou tópico de destino pretendido usando a mesma implementação de transferência robusta na qual o recurso de encaminhamento automático depende. A mensagem nunca é confirmada na fila de transferência ou no log do tópico de tal forma que se torna visível para os consumidores da fila de transferência ou do tópico.

O poder desse recurso transacional torna-se aparente quando a fila de transferência ou o próprio tópico é a fonte das mensagens de entrada do remetente. Em outras palavras, o Service Bus pode transferir a mensagem para a fila de destino ou tópico "via" da fila de transferência ou tópico, enquanto executa uma operação completa (ou adiar, ou letra morta) na mensagem de entrada, tudo em uma operação atômica.

Se você precisar receber de uma assinatura de tópico e, em seguida, enviar para uma fila ou tópico na mesma transação, a entidade de transferência deve ser um tópico. Nesse cenário, inicie o escopo da transação no tópico, receba da assinatura com no escopo da transação e envie por meio do tópico de transferência para uma fila ou destino do tópico.

Nota

  • Se uma mensagem é enviada através de uma fila de transferência no âmbito de uma transação, TransactionPartitionKey é funcionalmente equivalente a PartitionKey. Garante que as mensagens são mantidas juntas e em ordem à medida que são transferidas.
  • Se a fila ou o tópico de destino for excluído, uma exceção 404 será gerada.

Veja no código

Para configurar essas transferências, crie um remetente de mensagem direcionado à fila de destino por meio da fila de transferência. Você também tem um recetor que extrai mensagens dessa mesma fila. Por exemplo:

Uma transação simples usa esses elementos, como no exemplo a seguir. Para consultar o exemplo completo, consulte o código-fonte no GitHub:

var options = new ServiceBusClientOptions { EnableCrossEntityTransactions = true };
await using var client = new ServiceBusClient(connectionString, options);

ServiceBusReceiver receiverA = client.CreateReceiver("queueA");
ServiceBusSender senderB = client.CreateSender("queueB");

ServiceBusReceivedMessage receivedMessage = await receiverA.ReceiveMessageAsync();

using (var ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
{
    await receiverA.CompleteMessageAsync(receivedMessage);
    await senderB.SendMessageAsync(new ServiceBusMessage());
    ts.Complete();
}

Para saber mais sobre a EnableCrossEntityTransactions propriedade, consulte a seguinte referência Método ServiceBusClientBuilder.enableCrossEntityTransactions.

Limite de tempo excedido

Uma transação expira após 2 minutos. O temporizador de transação começa quando a primeira operação na transação é iniciada.

Para obter mais informações sobre filas do Service Bus, consulte os seguintes artigos: