Mensagens em lote em uma transação

Os aplicativos em fila usam transações para garantir a correção e a entrega confiável de mensagens. As transações, no entanto, são operações caras e podem reduzir drasticamente a taxa de transferência de mensagens. Uma maneira de melhorar a taxa de transferência de mensagens é fazer com que um aplicativo leia e processe várias mensagens em uma única transação. A compensação é entre desempenho e recuperação: à medida que o número de mensagens em um lote aumenta, aumenta também a quantidade de trabalho de recuperação necessária se as transações forem revertidas. É importante observar a diferença entre mensagens em lote em uma transação e sessões. Uma sessão é um agrupamento de mensagens relacionadas que são processadas por um único aplicativo e confirmadas como uma única unidade. As sessões geralmente são usadas quando um grupo de mensagens relacionadas deve ser processado em conjunto. Um exemplo disso é um site de compras on-line. Os lotes são usados para processar várias mensagens não relacionadas de uma forma que aumenta a taxa de transferência de mensagens. Para obter mais informações sobre sessões, consulte Agrupando mensagens em fila em uma sessão. As mensagens em um lote também são processadas por um único aplicativo e confirmadas como uma única unidade, mas pode não haver relação entre as mensagens no lote. Enviar mensagens em lote em uma transação é uma otimização que não altera a forma como o aplicativo é executado.

Entrando no modo de processamento em lote

O TransactedBatchingBehavior comportamento do ponto de extremidade controla o envio em lote. Adicionar esse comportamento de ponto de extremidade a um ponto de extremidade de serviço informa ao Windows Communication Foundation (WCF) para enviar mensagens em lote em uma transação. Nem todas as mensagens exigem uma transação, portanto, apenas as mensagens que exigem uma transação são colocadas em um lote e apenas as mensagens enviadas de operações marcadas com TransactionScopeRequired = true e TransactionAutoComplete = true são consideradas para um lote. Se todas as operações no contrato de serviço estiverem marcadas com TransactionScopeRequired = false e , o modo de lote TransactionAutoComplete = falsenunca será inserido.

Confirmando uma transação

Uma transação em lote é confirmada com base no seguinte:

  • MaxBatchSize. Uma propriedade do TransactedBatchingBehavior comportamento. Essa propriedade determina o número máximo de mensagens que são colocadas em um lote. Quando esse número é atingido, o lote é comprometido. Este valor não é um limite estrito, é possível comprometer um lote antes de receber este número de mensagens.

  • Transaction Timeout. Após 80% do tempo limite da transação ter decorrido, o lote é confirmado e um novo lote é criado. Isso significa que, se 20% ou menos do tempo dado para uma transação ser concluída permanecer, o lote será comprometido.

  • TransactionScopeRequired. Ao processar um lote de mensagens, se o WCF encontrar um que tenha TransactionScopeRequired = false, ele confirmará o lote e reabrirá um novo lote ao receber a primeira mensagem com = trueTransactionScopeRequirede .TransactionAutoComplete = true

  • Se não existirem mais mensagens na fila, o lote atual será confirmado, mesmo que o MaxBatchSize não tenha sido atingido ou 80% do tempo limite da transação não tenha decorrido.

Saindo do modo de processamento em lote

Se uma mensagem em um lote fizer com que a transação seja anulada, as seguintes etapas ocorrerão:

  1. Todo o lote de mensagens é revertido.

  2. As mensagens são lidas uma de cada vez até que o número de mensagens lidas exceda o dobro do tamanho máximo do lote.

  3. O modo de lote é reinserido.

Escolhendo o tamanho do lote

O tamanho de um lote depende do aplicativo. O método empírico é a melhor maneira de chegar a um tamanho de lote ideal para a aplicação. É importante lembrar ao escolher um tamanho de lote para escolher o tamanho de acordo com o modelo de implantação real do seu aplicativo. Por exemplo, ao implantar o aplicativo, se você precisar de um servidor SQL em uma máquina remota e uma transação que abranja a fila e o servidor SQL, o tamanho do lote é melhor determinado executando essa configuração exata.

Simultaneidade e processamento em lote

Para aumentar a taxa de transferência, você também pode ter muitos lotes executados simultaneamente. Ao definir ConcurrencyMode.Multiple o ServiceBehaviorAttribute, você habilita o envio em lote simultâneo.

A limitação de serviço é um comportamento de serviço usado para indicar quantas chamadas simultâneas máximas podem ser feitas no serviço. Quando usado com lotes, isso é interpretado como quantos lotes simultâneos podem ser executados. Se a limitação do serviço não estiver definida, o WCF padronizará o máximo de chamadas simultâneas para 16. Assim, se o comportamento de lote foi adicionado por padrão, um máximo de 16 lotes podem estar ativos ao mesmo tempo. É melhor ajustar a limitação do serviço e o processamento em lote com base na sua capacidade. Por exemplo, se a fila tiver 100 mensagens e um lote de 20 for desejado, ter o máximo de chamadas simultâneas definido como 16 não é útil porque, dependendo da taxa de transferência, 16 transações podem estar ativas, semelhante a não ter o lote ativado. Portanto, ao ajustar o desempenho, não tenha lote simultâneo ou tenha lote simultâneo com o tamanho correto do acelerador de serviço.

Processamento em lote e vários endpoints

Um ponto de extremidade é composto por um endereço e um contrato. Pode haver vários pontos de extremidade que compartilham a mesma ligação. É possível que dois pontos de extremidade compartilhem a mesma ligação e ouçam o URI (Uniform Resource Identifier) ou o endereço da fila. Se dois pontos de extremidade estiverem sendo lidos da mesma fila e o comportamento de lote transacionado for adicionado a ambos os pontos de extremidade, poderá surgir um conflito nos tamanhos de lote especificados. Isso é resolvido implementando o processamento em lote usando o tamanho mínimo de lote especificado entre os dois comportamentos de lote transacionados. Nesse cenário, se um dos pontos de extremidade não especificar o lote transacionado, ambos os pontos de extremidade não usarão o lote.

Exemplo

O exemplo a seguir mostra como especificar o TransactedBatchingBehavior em um arquivo de configuração.

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

O exemplo a seguir mostra como especificar o TransactedBatchingBehavior código in.

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

Consulte também