Compartilhar via


Mensagens de lote em uma transação

Aplicativos na 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 está entre o desempenho e a recuperação: à medida que o número de mensagens em um lote aumenta, o mesmo acontece com a quantidade de trabalho de recuperação necessário se as transações forem revertidas. É importante observar a diferença entre envio em lote de mensagens 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 são geralmente usadas quando um grupo de mensagens relacionadas deve ser processado em conjunto. Um exemplo disso é um site de compras online. Os lotes são usados para processar várias mensagens não relacionadas de forma a aumentar a taxa de transferência da mensagem. Para obter mais informações sobre sessões, consulte Agrupar mensagens na 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 nenhuma 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.

Inserir o modo de envio em lote

O comportamento do participante TransactedBatchingBehavior controla o envio em lote. Adicionar esse comportamento de ponto de extremidade a um ponto de extremidade de serviço diz ao WCF (Windows Communication Foundation) para enviar em lote mensagens em uma transação. Nem todas as mensagens exigem uma transação, portanto, somente as mensagens que exigem uma transação são colocadas em um lote e somente 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 forem marcadas com TransactionScopeRequired = false e TransactionAutoComplete = false, o modo de envio em lote nunca será inserido.

Confirmando uma transação

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

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

  • Transaction Timeout. Depois que 80 por cento do tempo limite da transação tiver decorrido, o lote será confirmado e um novo lote será criado. Isso significa que, se sobrarem 20 por cento ou menos do tempo determinado para uma transação ser concluída, o lote será confirmado.

  • 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 TransactionScopeRequired = true e TransactionAutoComplete = true.

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

Sair do modo de envio 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 envio em lote é inserido novamente.

Escolher 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 o aplicativo. Ao escolher um tamanho de lote, é importante lembrar de escolher o tamanho de acordo com o modelo de implantação real do aplicativo. Por exemplo, ao implantar o aplicativo, se você precisar de um servidor SQL em um computador remoto e uma transação que abranja a fila e o servidor SQL, o tamanho do lote será melhor determinado executando essa configuração exata.

Simultaneidade e envio em lote

Para aumentar a taxa de transferência, você também pode ter vários lotes executados simultaneamente. Ao configurar ConcurrencyMode.Multiple em 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 o envio em lote, isso é interpretado como quantos lotes simultâneos podem ser executados. Se a limitação do serviço não estiver definida, o WCF usará como padrão o máximo de chamadas simultâneas para 16. Assim, se o comportamento de envio em lote tiver sido adicionado por padrão, 16 lotes, no máximo, poderão estar ativos ao mesmo tempo. É melhor ajustar a limitação de serviço e o envio em lote com base em sua capacidade. Por exemplo, se a fila tiver 100 mensagens e um lote de 20 for desejado, ter as chamadas simultâneas máximas definidas como 16 não será útil porque, dependendo da taxa de transferência, 16 transações podem estar ativas, semelhantemente a não ter o envio em lote ativado. Portanto, ao ajustar o desempenho, não tenha lote em lote simultâneo ou tenha o envio em lote simultâneo com o tamanho correto da limitação do serviço.

Envio em lote e vários pontos de extremidade

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

Exemplo

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

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

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

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

Confira também