Overzicht van Service Bus-transactieverwerking

In dit artikel worden de transactiemogelijkheden van Microsoft Azure Service Bus besproken. Veel van de discussie wordt geïllustreerd door het voorbeeld van transacties. Dit artikel is beperkt tot een overzicht van transactieverwerking en de functie verzenden via service bus, terwijl het voorbeeld Atomic Transactions breder en complexer is binnen het bereik.

Notitie

  • De Basic-laag van Service Bus biedt geen ondersteuning voor transacties. De standard- en premium-lagen bieden ondersteuning voor transacties. Zie Service Bus-prijzen voor verschillen tussen deze lagen.
  • Het combineren van beheer- en berichtenbewerkingen in een transactie wordt niet ondersteund.
  • JavaScript SDK biedt geen ondersteuning voor transacties.

Transacties in Service Bus

Een transactie groeperen twee of meer bewerkingen in een uitvoeringsbereik. Een dergelijke transactie moet er van nature voor zorgen dat alle bewerkingen die tot een bepaalde groep bewerkingen behoren, gezamenlijk slagen of mislukken. In dit opzicht fungeren transacties als één eenheid, die vaak atomisch wordt genoemd.

Service Bus is een transactionele berichtenbroker en zorgt voor transactionele integriteit voor alle interne bewerkingen ten opzichte van de berichtenarchieven. Alle overdrachten van berichten in Service Bus, zoals het verplaatsen van berichten naar een wachtrij met onbestelbare berichten of het automatisch doorsturen van berichten tussen entiteiten, zijn transactioneel. Als Service Bus een bericht accepteert, is het bericht al opgeslagen en gelabeld met een volgnummer. Vanaf dat tijdstip zijn alle berichtoverdrachten binnen Service Bus gecoördineerde bewerkingen tussen entiteiten en leiden ze niet tot verlies (bron is geslaagd en doel mislukt) of duplicatie (bron mislukt en doel slaagt) van het bericht.

Service Bus biedt ondersteuning voor het groeperen van bewerkingen voor één berichtentiteit (wachtrij, onderwerp of abonnement) binnen het bereik van een transactie. U kunt bijvoorbeeld meerdere berichten verzenden naar één wachtrij binnen een transactiebereik en de berichten worden alleen doorgevoerd in het logboek van de wachtrij wanneer de transactie is voltooid.

Bewerkingen binnen een transactiebereik

De bewerkingen die binnen een transactiebereik kunnen worden uitgevoerd, zijn als volgt:

  • Verzenden
  • Voltooid
  • Afbreken
  • Deadletter
  • Uitstellen
  • Vergrendelen vernieuwen

Ontvangstbewerkingen worden niet opgenomen, omdat wordt ervan uitgegaan dat de toepassing berichten verkrijgt met behulp van de peek-lock-modus, binnen een ontvangstlus of met een callback, en alleen vervolgens een transactiebereik opent voor het verwerken van het bericht.

De verwijdering van het bericht (volledig, verlaten, dode letter, uitstellen) vindt vervolgens plaats binnen het bereik van en afhankelijk van het algehele resultaat van de transactie.

Belangrijk

Azure Service Bus voert een bewerking niet opnieuw uit in het geval van een uitzondering wanneer de bewerking zich in een transactiebereik bevindt.

Bewerkingen die niet worden opgenomen in transactiebereiken

Houd er rekening mee dat berichtverwerkingscode die databases en andere services zoals Cosmos DB aanroept, deze downstream-resources niet automatisch in hetzelfde transactionele bereik opgeeft. Bekijk de richtlijnen voor het verwerken van idempotente berichten voor meer informatie over het afhandelen van deze scenario's.

Overdrachten en verzenden via

Service Bus ondersteunt overdrachten om transactionele overdracht van gegevens uit een wachtrij of onderwerp naar een processor in te schakelen en vervolgens naar een andere wachtrij of ander onderwerp. In een overdrachtsbewerking verzendt een afzender eerst een bericht naar een overdrachtswachtrij of -onderwerp en verplaatst de overdrachtswachtrij of het onderwerp het bericht onmiddellijk naar de beoogde doelwachtrij of het beoogde doelonderwerp met behulp van dezelfde robuuste overdrachts-implementatie waarop de functie voor automatisch doorsturen afhankelijk is. Het bericht wordt nooit doorgevoerd in de overdrachtswachtrij of het logboek van het onderwerp, zodat het zichtbaar wordt voor de gebruikers van de overdrachtswachtrij of het onderwerp.

De kracht van deze transactionele mogelijkheid wordt duidelijk wanneer de overdrachtswachtrij of het onderwerp zelf de bron is van de invoerberichten van de afzender. Met andere woorden, Service Bus kan het bericht overbrengen naar de doelwachtrij of het onderwerp 'via' de overdrachtswachtrij of het onderwerp, terwijl een volledige bewerking (of uitstellen of dode letters) wordt uitgevoerd op het invoerbericht, allemaal in één atomische bewerking.

Als u een onderwerpabonnement moet ontvangen en vervolgens naar een wachtrij of onderwerp in dezelfde transactie moet verzenden, moet de overdrachtsentiteit een onderwerp zijn. In dit scenario start u het transactiebereik voor het onderwerp, ontvangt u van het abonnement in het transactiebereik en verzendt u via het overdrachtsonderwerp naar een wachtrij of onderwerpbestemming.

Notitie

Als een bericht wordt verzonden via een overdrachtswachtrij binnen het bereik van een transactie, TransactionPartitionKey is dit functioneel gelijk aan PartitionKey. Het zorgt ervoor dat berichten bij elkaar worden gehouden en in volgorde worden overgebracht.

Zie het in code

Als u dergelijke overdrachten wilt instellen, maakt u een berichtzender die gericht is op de doelwachtrij via de overdrachtswachtrij. U hebt ook een ontvanger waarmee berichten uit dezelfde wachtrij worden opgehaald. Bijvoorbeeld:

Een eenvoudige transactie gebruikt deze elementen, zoals in het volgende voorbeeld. Raadpleeg de broncode op GitHub om naar het volledige voorbeeld te verwijzen:

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();
}

Zie de volgende referentiemethode ServiceBusClientBuilder.enableCrossEntityTransactions voor meer informatie over de EnableCrossEntityTransactions eigenschap.

Timeout

Er treedt een time-out op voor een transactie na 2 minuten. De transactietimer wordt gestart wanneer de eerste bewerking in de transactie wordt gestart.

Volgende stappen

Zie de volgende artikelen voor meer informatie over Service Bus-wachtrijen: