Uso ExecuteMultiple para melhorar o desempenho do carregamento de dados em massa

 

Publicado: janeiro de 2017

Aplicável a: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

Você pode usar a mensagem ExecuteMultipleRequest para suportar uma mensagem em massa mais alta taxa de transferência transmitindo cenários Microsoft Dynamics 365 (online e local), especialmente no caso Microsoft Dynamics 365 (online) na latência da Internet pode ser o fatora limitação do maior.ExecuteMultipleRequest aceita uma coleção de entrada de mensagens Requests, execute todas as solicitações no pedido de mensagens exibidas no conjunto de entrada e, opcionalmente retorna uma coleção Responses que contém a resposta ou o de cada mensagem erros ocorridos. Cada solicitação de mensagem na coleção de entrada é processada em uma transação do banco de dados separado. O ExecuteMultipleRequest é executado usando o método IOrganizationService.Execute.

Geralmente, o ExecuteMultipleRequest comporta-se da mesma forma se você executou cada solicitação de mensagem no conjunto de solicitações de entrada separadamente, exceto com um melhor desempenho. O uso do parâmetros CallerId do proxy de serviço é aceito e será aplicado na execução de cada mensagem no conjunto de solicitações de entrada. Os plug-ins e as atividades de fluxo de trabalho são executados como você espera para cada mensagem processada.

Código personalizado na forma de plug-ins e atividades de fluxo de trabalho personalizado pode até executar o ExecuteMultipleRequest. Entretanto, há alguns pontos-chave para lembrar. Uma exceção acionada por um plug-in registrado sincronizado é retornado no parâmetro Fault do item da coleção de resposta. Se um plug-in executar dentro de uma transação do banco de dados, ele executa o ExecuteMultipleRequest e uma reversão de transação é iniciada. A reversão inclui todas as alterações de dados resultantes de solicitações executadas pelo ExecuteMultipleRequest.

Neste tópico

Exemplo

Especificar opções de execução do tempo de execução

Limites do tempo de execução

Manipular uma falha de tamanho do lote

Exemplo

O seguinte código de exemplo mostra um único ExecuteMultipleRequest que executa várias operações de criação. As opções de execução do tempo de execução chamadas de Configurações são usadas para controlar o processamento da solicitação e os resultados retornados. Essas opções de tempo de execução são discutidas na próxima seção.


// Get a reference to the organization service.
using (_serviceProxy = new OrganizationServiceProxy(serverConfig.OrganizationUri, serverConfig.HomeRealmUri,serverConfig.Credentials, serverConfig.DeviceCredentials))
{
    // Enable early-bound type support to add/update entity records required for this sample.
    _serviceProxy.EnableProxyTypes();

    #region Execute Multiple with Results
    // Create an ExecuteMultipleRequest object.
    requestWithResults = new ExecuteMultipleRequest()
    {
        // Assign settings that define execution behavior: continue on error, return responses. 
        Settings = new ExecuteMultipleSettings()
        {
            ContinueOnError = false,
            ReturnResponses = true
        },
        // Create an empty organization request collection.
        Requests = new OrganizationRequestCollection()
    };

    // Create several (local, in memory) entities in a collection. 
    EntityCollection input = GetCollectionOfEntitiesToCreate();

    // Add a CreateRequest for each entity to the request collection.
    foreach (var entity in input.Entities)
    {
        CreateRequest createRequest = new CreateRequest { Target = entity };
        requestWithResults.Requests.Add(createRequest);
    }

    // Execute all the requests in the request collection using a single web method call.
    ExecuteMultipleResponse responseWithResults =
        (ExecuteMultipleResponse)_serviceProxy.Execute(requestWithResults);

    // Display the results returned in the responses.
    foreach (var responseItem in responseWithResults.Responses)
    {
        // A valid response.
        if (responseItem.Response != null)
            DisplayResponse(requestWithResults.Requests[responseItem.RequestIndex], responseItem.Response);

        // An error has occurred.
        else if (responseItem.Fault != null)
            DisplayFault(requestWithResults.Requests[responseItem.RequestIndex], 
                responseItem.RequestIndex, responseItem.Fault);
    }

' Get a reference to the organization service.
_serviceProxy = ServerConnection.GetOrganizationProxy(serverConfig)

Using _serviceProxy
    ' Enable early-bound type support to add/update entity records required for this sample.
    _serviceProxy.EnableProxyTypes()

    '#Region "Execute Multiple with Results"
    ' Create an ExecuteMultipleRequest object.
    ' Assign settings that define execution behavior: continue on error, return responses.
    ' Create an empty organization request collection.
    requestWithResults = New ExecuteMultipleRequest() With
        {
            .Settings = New ExecuteMultipleSettings() With
                        {
                            .ContinueOnError = False,
                            .ReturnResponses = True
                        },
            .Requests = New OrganizationRequestCollection()
        }

    ' Create several (local, in memory) entities in a collection. 
    Dim input As EntityCollection = GetCollectionOfEntitiesToCreate()

    ' Add a CreateRequest for each entity to the request collection.
    For Each entity In input.Entities
        Dim createRequest_Renamed As CreateRequest = New CreateRequest With {.Target = entity}
        requestWithResults.Requests.Add(createRequest_Renamed)
    Next entity

    ' Execute all the requests in the request collection using a single web method call.
    Dim responseWithResults As ExecuteMultipleResponse =
        CType(_serviceProxy.Execute(requestWithResults), ExecuteMultipleResponse)

    ' Display the results returned in the responses.
    For Each responseItem In responseWithResults.Responses

        If responseItem.Response IsNot Nothing Then
            ' A valid response.
            DisplayResponse(requestWithResults.Requests(responseItem.RequestIndex),
                            responseItem.Response)

        ElseIf responseItem.Fault IsNot Nothing Then
            ' An error has occurred.
            DisplayFault(requestWithResults.Requests(responseItem.RequestIndex),
                         responseItem.RequestIndex, responseItem.Fault)
        End If
    Next responseItem

Para exibir o exemplo completo, consulte Exemplo: Execute várias solicitações.

Especificar opções de execução do tempo de execução

O parâmetro Settings de ExecuteMultipleRequest se aplica a todas as solicitações no conjunto de solicitação controlando o comportamento da execução e os resultados retornados. Vamos olhar essas opções em mais detalhe.

Membro ExecuteMultipleSettings

Descrição

ContinueOnError

Quando true, continua a processar a próxima solicitação no conjunto mesmo se uma falha foi retornada do processamento da solicitação atual na coleção. Quando false, não continue a processar a próxima solicitação.

ReturnResponses

Quando true, retorna respostas de cada solicitação de mensagem processada. Quando false, não retorna respostas.

Se definido como true e a solicitação não retorna uma resposta, porque é seu design, o ExecuteMultipleResponseItem para essa solicitação é definido como null.

No entanto, mesmo quando false, a coleção Responses não estará vazia se os erros forem retornados. Se os erros forem retornados, haverá um item de resposta em uma coleção para cada solicitação processada que retornou uma falha e Fault será definido como a falha real que ocorreu.

Por exemplo, em uma coleção de solicitações que contém seis solicitações onde a terceira e quinta solicitação retorna falha, a tabela a seguir indica que a coleção Responses conteria.

Configurações

Conteúdo da coleção de respostas

ContinueOnError=true, ReturnResponses=true

6 itens de resposta: 2 com Fault definidos para um valor.

ContinueOnError=false, ReturnResponses=true

3 itens de resposta: 1 com Fault definido para um valor.

ContinueOnError=true, ReturnResponses=false

2 itens de resposta: 2 com Fault definidos para um valor.

ContinueOnError=false, ReturnResponses=false

1 item de resposta: 1 com Fault definido para um valor.

Um parâmetro RequestIndex no item de resposta indica o número de sequência, começando em zero, da solicitação na qual a resposta está associada. No exemplo anterior, a terceira solicitação tem um índice de solicitação de 2.

Limites do tempo de execução

Há várias restrições relacionadas ao uso do ExecuteMultipleRequest conforme descrito na lista a seguir.

  • Nenhuma recursão é permitida - ExecuteMultipleRequest não pode chamar ExecuteMultipleRequest. Um ExecuteMultipleRequest encontrado no conjunto de solicitação gerará uma falha do item de solicitação.

  • Tamanho máximo de lote – há um limite de quantas solicitações podem ser adicionadas a uma coleção de solicitação. Se esse limite for excedido, uma falha será lançada antes da primeira solicitação ser executada. Um limite de 1000 solicitações é comum, embora essa quantidade máxima possa ser definida para a implantação do Microsoft Dynamics 365. A configuração de implantação para esse limite é BatchSize.

  • Estrangulamento de chamadas simultâneas – para o Microsoft Dynamics 365 (online) há um limite de 2 execuções ExecuteMultipleRequest simultâneas por organização. Se esse limite for excedido, uma falha "Servidor Ocupado" será lançada antes da primeira solicitação ser executada. Para uma implantação local, o estrangulamento não está habilitado por padrão. A configuração de implantação para esse limite é ExecuteAsyncPerOrgMaxConnectionsPerServer.

    Dica

    Para toda a implantação de Dynamics 365, um administrador de implantação pode definir ou alterar o limite de restrição.

Manipular uma falha de tamanho do lote

O que fazer quando sua coleção de solicitação de entrada excede o tamanho máximo do lote? O código não consultar diretamente o tamanho máximo do lote através do serviço Web de implantação a menos que esteja em execução em uma conta com a função de administrador de implantação.

Felizmente, há outro método que pode ser usado. Quando o número de solicitações na coleção Requests de entrada excede o tamanho máximo do lote permitido para uma organização, é retornada uma falha da chamada ExecuteMultipleRequest. O tamanho máximo do lote é retorna na falha. Seu código pode verificar esse valor, redimensionar a coleção de solicitações de entrada para estar dentro do limite indicado e reenviar o ExecuteMultipleRequest. O trecho de código a seguir demonstra parte dessa lógica.


catch (FaultException<OrganizationServiceFault> fault)
{
    // Check if the maximum batch size has been exceeded. The maximum batch size is only included in the fault if it
    // the input request collection count exceeds the maximum batch size.
    if (fault.Detail.ErrorDetails.Contains("MaxBatchSize"))
    {
        int maxBatchSize = Convert.ToInt32(fault.Detail.ErrorDetails["MaxBatchSize"]);
        if (maxBatchSize < requestWithResults.Requests.Count)
        {
            // Here you could reduce the size of your request collection and re-submit the ExecuteMultiple request.
            // For this sample, that only issues a few requests per batch, we will just print out some info. However,
            // this code will never be executed because the default max batch size is 1000.
            Console.WriteLine("The input request collection contains %0 requests, which exceeds the maximum allowed (%1)",
                requestWithResults.Requests.Count, maxBatchSize);
        }
    }
    // Re-throw so Main() can process the fault.
    throw;
}

Catch fault As FaultException(Of OrganizationServiceFault)

    ' Check if the maximum batch size has been exceeded. The maximum batch size is only included in the fault if it
    ' the input request collection count exceeds the maximum batch size.
    If fault.Detail.ErrorDetails.Contains("MaxBatchSize") Then

        Dim maxBatchSize As Integer = Convert.ToInt32(fault.Detail.ErrorDetails("MaxBatchSize"))
        If maxBatchSize < requestWithResults.Requests.Count Then
            ' Here you could reduce the size of your request collection and re-submit the ExecuteMultiple request.
            ' For this sample, that only issues a few requests per batch, we will just print out some info. However,
            ' this code will never be executed because the default max batch size is 1000.
            Console.WriteLine("The input request collection contains %0 requests, which exceeds the maximum allowed (%1)", requestWithResults.Requests.Count, maxBatchSize)
        End If
    End If
    ' Re-throw so Main() can process the fault.
    Throw
End Try

Confira Também

Execute
OrganizationRequest
OrganizationResponse
Use o Serviço da organização para ler e gravar dados ou metadados
Mensagens do xRM no serviço da organização
Mensagens no serviço de descoberta
Mensagens no serviço de organização do Dynamics 365
Importar dados

Microsoft Dynamics 365

© 2017 Microsoft. Todos os direitos reservados. Direitos autorais