Dávkování zpráv v transakci

Aplikace ve frontě používají transakce k zajištění správnosti a spolehlivého doručování zpráv. Transakce jsou ale nákladné operace a mohou výrazně snížit propustnost zpráv. Jedním ze způsobů, jak zlepšit propustnost zpráv, je čtení a zpracování více zpráv v rámci jedné transakce. Kompromis je mezi výkonem a obnovením: s rostoucím počtem zpráv v dávce, takže množství práce na obnovení, která se vyžaduje v případě vrácení transakcí zpět. Je důležité si uvědomit rozdíl mezi dávkovými zprávami v transakci a relacích. Relace je seskupení souvisejících zpráv, které jsou zpracovány jednou aplikací a potvrzeny jako jedna jednotka. Relace se obvykle používají, když se musí zpracovat skupina souvisejících zpráv společně. Příkladem je web online nakupování. Dávky se používají ke zpracování více nesouvisejících zpráv způsobem, který zvyšuje propustnost zpráv. Další informace o relacích naleznete v tématu Seskupování zpráv zařazených do fronty v relaci. Zprávy v dávce jsou také zpracovány jednou aplikací a potvrzeny jako jedna jednotka, ale mezi zprávami v dávce nemusí existovat žádný vztah. Dávkování zpráv v transakci je optimalizace, která nemění způsob spouštění aplikace.

Vstup do režimu dávkování

Chování TransactedBatchingBehavior koncového bodu řídí dávkování. Přidání tohoto chování koncového bodu do koncového bodu služby informuje windows Communication Foundation (WCF) o dávkových zprávách v transakci. Ne všechny zprávy vyžadují transakci, takže pouze zprávy, které vyžadují transakci, jsou umístěny v dávce a pouze zprávy odeslané z operací označených TransactionScopeRequired = true a TransactionAutoComplete = true jsou považovány za dávky. Pokud jsou všechny operace ve smlouvě o poskytování služeb označené TransactionScopeRequired = false a TransactionAutoComplete = falserežim dávkování se nikdy nezadá.

Potvrzení transakce

Dávková transakce je potvrzena na základě následujících:

  • MaxBatchSize. Vlastnost TransactedBatchingBehavior chování. Tato vlastnost určuje maximální počet zpráv, které jsou umístěny do dávky. Po dosažení tohoto čísla se dávka potvrdí. Tato hodnota není přísný limit, je možné před přijetím tohoto počtu zpráv potvrdit dávku.

  • Transaction Timeout. Po uplynutí 80 % časového limitu transakce se dávka potvrdí a vytvoří se nová dávka. To znamená, že pokud zbývá 20 procent nebo méně času pro dokončení transakce, dávka se potvrdí.

  • TransactionScopeRequired. Při zpracování dávky zpráv, pokud WCF najde jednu, která obsahuje TransactionScopeRequired = false, potvrdí dávku a znovu otevře novou dávku při přijetí první zprávy strue = TransactionScopeRequired a .TransactionAutoComplete = true

  • Pokud ve frontě neexistují žádné další zprávy, aktuální dávka se potvrdí, i když MaxBatchSize nebyla dosažena nebo 80 % časového limitu transakce nevyplnělo.

Opuštění režimu dávkování

Pokud zpráva v dávce způsobí přerušení transakce, dojde k následujícím krokům:

  1. Celá dávka zpráv se vrátí zpět.

  2. Zprávy se čtou po jednom, dokud počet přečtených zpráv nepřekročí dvojnásobek maximální velikosti dávky.

  3. Režim dávky se znovu zadá.

Volba velikosti dávky

Velikost dávky je závislá na aplikaci. Empirická metoda je nejlepší způsob, jak dosáhnout optimální velikosti dávky pro aplikaci. Při výběru velikosti dávky je důležité pamatovat na to, že zvolíte velikost podle skutečného modelu nasazení vaší aplikace. Pokud například při nasazování aplikace potřebujete SQL server na vzdáleném počítači a transakci, která zahrnuje frontu a SQL server, je velikost dávky nejlépe určena spuštěním této přesné konfigurace.

Souběžnost a dávkování

Pokud chcete zvýšit propustnost, můžete také souběžně spouštět mnoho dávek. Nastavením této ServiceBehaviorAttributemožnosti ConcurrencyMode.Multiple povolíte souběžné dávkování.

Omezování služby je chování služby, které se používá k označení, kolik maximálních souběžných volání je možné ve službě provést. Při použití s dávkováním se to interpretuje jako počet souběžných dávek,kteréch Pokud není nastavené omezování služby, wcf nastaví maximální počet souběžných volání na 16. Pokud se tedy ve výchozím nastavení přidalo chování dávkování, může být současně aktivní maximálně 16 dávek. Nejlepší je vyladit omezování služby a dávkování na základě vaší kapacity. Pokud má například fronta 100 zpráv a vyžaduje se dávka 20, maximální počet souběžných volání nastavený na 16 není užitečný, protože v závislosti na propustnosti může být 16 transakcí aktivních, podobně jako když nemáte zapnuté dávkování. Proto při jemném ladění výkonu buď nemá souběžné dávkování nebo souběžné dávkování se správnou velikostí omezení služby.

Dávkování a více koncových bodů

Koncový bod se skládá z adresy a kontraktu. Může existovat několik koncových bodů, které sdílejí stejnou vazbu. Dva koncové body můžou sdílet stejnou vazbu a naslouchat identifikátoru URI (Uniform Resource Identifier) nebo adrese fronty. Pokud se dva koncové body čtou ze stejné fronty a do obou koncových bodů se přidá chování při dávkovém dávkování, může dojít ke konfliktu v zadaných velikostech dávek. Tento problém se vyřeší implementací dávkování s minimální velikostí dávky zadanou mezi těmito dvěma chováními při dávkování. Pokud jeden z koncových bodů v tomto scénáři nezadá dávkování transakcí, oba koncové body nebudou používat dávkování.

Příklad

Následující příklad ukazuje, jak zadat TransactedBatchingBehavior v konfiguračním souboru.

<behaviors>
  <endpointBehaviors>
    <behavior name="TransactedBatchingBehavior"
              maxBatchSize="100" />
  </endpointBehaviors>
</behaviors>

Následující příklad ukazuje, jak zadat TransactedBatchingBehavior v kódu.

using (ServiceHost serviceHost = new ServiceHost(typeof(OrderProcessorService)))
{
     ServiceEndpoint sep = ServiceHost.AddServiceEndpoint(typeof(IOrderProcessor), new NetMsmqBinding(), "net.msmq://localhost/private/ServiceModelSamplesTransacted");
     sep.Behaviors.Add(new TransactedBatchingBehavior(100));

     // Open the ServiceHost to create listeners and start listening for messages.
    serviceHost.Open();
  
    // The service can now be accessed.
    Console.WriteLine("The service is ready.");
    Console.WriteLine("Press <ENTER> to terminate service.");
    Console.WriteLine();
    Console.ReadLine();
  
    // Close the ServiceHostB to shut down the service.
    serviceHost.Close();
}  

Viz také