Partekatu honen bidez:


Usar ExecuteMultiple para mejorar el rendimiento de la carga masiva de datos

 

Publicado: enero de 2017

Se aplica a: Dynamics 365 (online), Dynamics 365 (on-premises), Dynamics CRM 2016, Dynamics CRM Online

Puede usar el mensaje ExecuteMultipleRequest para apoyar escenarios de paso de mensajes en masa con un mayor rendimiento en Microsoft Dynamics 365 (en línea y local), especialmente en el caso de Microsoft Dynamics 365 (online) donde la latencia de Internet puede ser el mayor factor limitador.ExecuteMultipleRequest acepta una colección de entrada de Requests de mensajes, ejecuta cada una de las solicitudes de mensajes en el orden que aparecen en la colección de entrada y opcionalmente devuelve una colección de Responses que contiene la respuesta de cada mensaje o el error que se han producido. Cada solicitud de mensaje en la colección de entrada se procesa en una transacción independiente de la base de datos.ExecuteMultipleRequest se ejecuta usando el método IOrganizationService.Execute.

En general, ExecuteMultipleRequest se comporta de la misma manera que si ejecutara cada solicitud de mensaje en la colección de solicitudes de entrada por separado, excepto que con mejor rendimiento. Se respeta el uso del parámetro CallerId del proxy de servicio y se aplicará a la ejecución de cada mensaje en la colección de solicitudes de entrada. Los complementos y las actividades de flujo de trabajo se ejecutan como se podría esperar para cada mensaje procesado.

Incluso el código personalizado en la forma de complementos y actividades personalizadas del flujo de trabajo puede ejecutar ExecuteMultipleRequest. Sin embargo, hay algunos puntos clave para tener en cuenta. Se devuelve una excepción generada por un complemento registrado sincrónico en el parámetro Fault del elemento de la colección de respuesta. Si un complemento se ejecuta en una transacción de la base de datos, el complemento ejecuta ExecuteMultipleRequest, y se inicia una reversión de la transacción, la cual incluye los cambios de datos que derivan de las solicitudes ejecutadas por ExecuteMultipleRequest.

En este tema

Ejemplo

Especificación de las opciones de ejecución en tiempo de ejecución

Limitaciones al tiempo de ejecución

Cómo administrar un error de tamaño de lote

Ejemplo

El siguiente código de ejemplo muestra un solo ExecuteMultipleRequest que realiza varias operaciones de creación. Se utilizan opciones de ejecución en tiempo de ejecución denominadas Configuración para controlar el procesamiento de la solicitud y los resultados obtenidos. Estas opciones de tiempo de ejecución se tratan en la sección siguiente.


// 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 ver el ejemplo completo, consulte Ejemplo: ejecutar varias solicitudes.

Especificación de las opciones de ejecución en tiempo de ejecución

El parámetro Settings de ExecuteMultipleRequest se aplica a todas las solicitudes de la colección de solicitudes que controlan el comportamiento de ejecución y los resultados obtenidos. Analicemos estas opciones con mayor detalle.

Miembro de ExecuteMultipleSettings

Descripción

ContinueOnError

Si está establecida en true, siga procesando la siguiente solicitud de la colección aunque haya obtenido un error por procesar la solicitud actual en la colección. Si está establecida en false, no siga procesando la solicitud siguiente.

ReturnResponses

Si está establecida en true, devuelve las respuestas de cada solicitud de mensaje procesada. Si está establecida en false, no devuelve respuestas.

Si está establecida en true y una solicitud no devuelve una respuesta, porque ese es el diseño, el parámetro ExecuteMultipleResponseItem de esa solicitud se establece en null.

Sin embargo, aunque esté establecida en false, la colección de Responses no estará vacía si se devuelven errores. Si se devuelven errores, habrá un elemento de respuesta en la colección de cada solicitud procesada que devolvió un error y Fault se establecerá en el error real que se produjo.

Por ejemplo, para una colección de solicitudes que contiene seis solicitudes en las que la tercera y la quinta solicitud devuelven errores, la siguiente tabla indica qué contendría la colección de Responses.

Configuración

Contenido de la colección de respuestas

ContinueOnError=true, ReturnResponses=true

6 elementos de respuesta: 2 tienen Fault establecido en un valor.

ContinueOnError=false, ReturnResponses=true

3 elementos de respuesta: 1 tiene Fault establecido en un valor.

ContinueOnError=true, ReturnResponses=false

2 elementos de respuesta: 2 tienen Fault establecido en un valor.

ContinueOnError=false, ReturnResponses=false

1 elemento de respuesta: 1 tiene Fault establecido en un valor.

Un parámetro RequestIndex en el elemento de respuesta indica el número de secuencia, a partir de cero, de la solicitud con la que está asociada la respuesta. En el ejemplo anterior, la tercera solicitud tiene un índice de solicitudes de 2.

Limitaciones al tiempo de ejecución

Existen varias restricciones relacionadas con el uso de ExecuteMultipleRequest tal como se describe en la siguiente lista.

  • No se permite la recursión: ExecuteMultipleRequest no puede invocar a ExecuteMultipleRequest. Un parámetro ExecuteMultipleRequest que se encuentre en la colección de solicitudes generará un error para ese elemento de la solicitud.

  • Tamaño de lote máximo: hay un límite en cuanto a la cantidad de solicitudes que se pueden agregar a una colección de solicitudes. Si se supera ese límite, se genera un error incluso antes de que se ejecute la primera solicitud. Un límite de 1000 solicitudes es típico aunque este cantidad máxima puede establecerse para la implementación de Microsoft Dynamics 365. El valor de la implementación para este límite es BatchSize.

  • Limitación de llamadas simultáneas: para Microsoft Dynamics 365 (online) hay un límite de 2 ejecuciones simultáneas de ExecuteMultipleRequest por organización. Si se supera ese límite, se genera un error de "Servidor ocupado" incluso antes de que se ejecute la primera solicitud. Para la implementación local, la limitación no está habilitada de forma predeterminada. El valor de la implementación para este límite es ExecuteAsyncPerOrgMaxConnectionsPerServer.

    Sugerencia

    Para cualquier implementación de Dynamics 365, un administrador de implementaciones puede establecer o cambiar el límite máximo.

Cómo administrar un error de tamaño de lote

¿Qué debe hacer cuando la colección de solicitudes de entrada supera el tamaño de lote máximo? El código no puede consultar directamente el tamaño de lote máximo con el servicio web de implementación a menos que se ejecute con una cuenta que tiene el rol de administrador de implementaciones.

Afortunadamente, hay otro método que puede usar. Cuando el número de solicitudes en la colección Requests de entrada supera el tamaño de lote máximo permitido para una organización, la llamada ExecuteMultipleRequest devuelve un error. El tamaño de lote máximo se devuelve en el error. El código puede comprobar ese valor, cambiar el tamaño de la colección de solicitudes de entrada de que modo que esté dentro del límite indicado y volver a enviar ExecuteMultipleRequest. El siguiente fragmento de código muestra parte de esta 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

Ver también

Execute
OrganizationRequest
OrganizationResponse
Usar el servicio de organización para leer y escribir datos o metadatos
Mensajes de xRM en el servicio de organización
Mensajes del servicio de detección
Mensajes de Dynamics 365 en el servicio de la organización
Importar datos

Microsoft Dynamics 365

© 2017 Microsoft. Todos los derechos reservados. Copyright