다음을 통해 공유


ExecuteMultiple을 사용하여 대량 데이터 로드 성능 향상

 

게시 날짜: 2016년 11월

적용 대상: Dynamics CRM 2015

Microsoft Dynamics CRM 2015 및 Microsoft Dynamics CRM Online 2015 업데이트에서, 특히 인터넷 지연이 가장 큰 제한 요인일 수 있는 Microsoft Dynamics CRM Online의 경우에 ExecuteMultipleRequest 메시지를 사용하여 더 높은 처리량의 벌크 메시지 통과 시나리오를 지원할 수 있습니다.ExecuteMultipleRequest는 메시지 Requests의 입력 모음을 받아, 각 메시지 요청을 그것이 입력 모음에 나타나는 순서대로 집행하며, 옵션으로서 각 메시지의 반응 또는 발생 오류가 포함된 Responses의 모음을 반환합니다. 입력 모음의 각 메시지 요청은 별도 데이터베이스 처리에서 처리됩니다.ExecuteMultipleRequestIOrganizationService.Execute 방법을 사용하여 실행됩니다.

일반적으로 ExecuteMultipleRequest는 더 나은 성능을 제외하고 입력 요청 컬렉션에서 각 메시지 요청을 별도로 실행한 것과 동일하게 동작합니다. 서비스 프록시의 CallerId 매개 변수 사용은 입력 요청 컬렉션의 모든 메시지를 실행 하는 데 적용됩니다. 플러그 인 및 워크플로 활동은 처리되는 각 메시지에 대해 예상대로 실행됩니다.

플러그 인의 양식에서 사용자 지정 코드 및 사용자 지정 워크플로 활동은 ExecuteMultipleRequest도 실행할 수 있습니다. 그러나 몇 가지 주요 해야 할 사항이 있습니다. 등록된 동기 플러그 인에서 발생한 예외는 응답 컬렉션 항목 Fault 매개 변수에서 반환됩니다. 플러그 인이 데이터베이스 트랜잭션 내에서 실행되면 플러그 인은 ExecuteMultipleRequest를 실행하고 트랜잭션이 시작되고 롤백에는 ExecuteMultipleRequest에서 실행한 요청에서 변경된 모든 데이터가 포함됩니다.

이 항목의 내용

예제

런타임 실행 옵션 지정

실행 시간 제한

일괄 처리 크기 오류 처리

예제

다음 샘플 코드에서는 만들기 작업을 여러 개 수행하는 단일 ExecuteMultipleRequest를 보여 줍니다.설정이라는 런타임 실행 옵션은 요청 처리 및 반환된 결과를 제어하는 데 사용됩니다. 이러한 런타임 옵션은 다음 섹션에서 설명합니다.


// 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

전체 샘플을 보려면 샘플: 여러 요청 실행을 참조하십시오.

런타임 실행 옵션 지정

ExecuteMultipleRequestSettings 매개 변수는 실행 동작과 반환된 결과를 제어하는 요청 컬렉션의 모든 요청에 적용됩니다. 이러한 옵션을 자세히 살펴 보겠습니다.

ExecuteMultipleSettings 멤버

설명

ContinueOnError

true이면 컬렉션에서 현재 요청을 처리하는 중에 오류가 반환되어도 컬렉션의 다음 요청 처리를 계속합니다.false이면 다음 요청을 계속 처리하지 않습니다.

ReturnResponses

true이면 처리된 각 메시지 요청의 응답을 반환합니다.false이면 응답을 반환하지 않습니다.

true로 설정되고 요청에서 응답을 반환하지 않으면(디자인 때문) 해당 요청에 대한 ExecuteMultipleResponseItemnull로 설정됩니다.

하지만 false인 경우에도 오류가 반환될 경우 Responses 컬렉션은 비어 있지 않습니다. 오류가 반환되면 처리한 각 요청에 대해 컬렉션에 오류가 반환된 하나의 응답 항목이 있고 Fault는 발생한 실제 오류로 설정됩니다.

예를 들어 세 번째와 다섯 번째 요청이 오류를 반환하는 여섯 개 요청이 포함된 요청 컬렉션에서 다음 표는 Responses 컬렉션에 포함되는 내용을 나타냅니다.

설정

응답 컬렉션 내용

ContinueOnError=true, ReturnResponses=true

6개 응답 항목: 2개 값 Fault 설정.

ContinueOnError=false, ReturnResponses=true

3개 응답 항목: 1개 값 Fault 설정.

ContinueOnError=true, ReturnResponses=false

2개 응답 항목: 2개 Fault 설정.

ContinueOnError=false, ReturnResponses=false

1개 응답 항목: 1개 값 Fault 설정.

응답 항목의 RequestIndex 매개 변수는 응답이 연결된 요청의 일련 번호(0부터 시작)를 나타냅니다. 앞의 예제에서 세 번째 요청의 요청 인덱스가 2였습니다.

실행 시간 제한

다음 목록에서 설명하는 ExecuteMultipleRequest 사용과 관련된 몇 가지 제한 사항이 있습니다.

  • 반복 허용되지 않음 - ExecuteMultipleRequestExecuteMultipleRequest를 호출할 수 없습니다. 요청 컬렉션에서 ExecuteMultipleRequest를 찾으면 해당 요청 항목에 대해 오류가 발생합니다.

  • 최대 일괄 처리 크기 – 요청 컬렉션에 추가할 수 있는 요청 수에 제한이 있습니다. 제한값을 초과하는 경우 첫 번째 요청이 실행되기 전에 오류가 발생합니다. 최대 값은 Microsoft Dynamics 365 배포에 대해 설정할 수 있지만 일반적으로 요청 1000개로 제한됩니다. 이 제한에 대한 배포 설정은 BatchSize입니다.

  • 동시 호출 제한 – Microsoft Dynamics CRM Online의 경우 조직 당 ExecuteMultipleRequest 동시 실행 2개로 제한됩니다. 제한값을 초과하는 경우 첫 번째 요청이 실행되기 전에 "서버 사용 중" 오류가 발생합니다. 온-프레미스 배포의 경우 기본적으로 제한이 활성화되어 있지 않습니다. 이 제한에 대한 배포 설정은 ExecuteAsyncPerOrgMaxConnectionsPerServer입니다.

일괄 처리 크기 오류 처리

사용자 입력 요청 컬렉션이 최대 일괄 처리 크기를 초과하는 경우 어떻게 해야 합니까? 배포 관리자 역할이 있는 계정에서 실행되지 않는 경우 코드에서 배포 웹 서비스를 통해 최대 일괄 처리 크기를 직접 쿼리할 수 없습니다.

다행히 다른 방법을 사용할 수 있습니다. 입력 Requests 컬렉션의 요청 수가 조직에서 허용하는 최대 일괄 처리 크기를 초과하면 ExecuteMultipleRequest 호출에서 오류가 반환됩니다. 최대 일괄 처리 크기가 오류로 반환됩니다. 코드에서 해당 값을 확인하고, 입력 요청 컬렉션을 표시된 제한 안으로 크기를 조정한 후 ExecuteMultipleRequest를 다시 제출합니다. 다음 코드 조각은 이 논리의 일부를 보여 줍니다.


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

참고 항목

Execute
OrganizationRequest
OrganizationResponse
IOrganizationService 웹 서비스를 사용하여 데이터 또는 메타데이터 읽기 및 쓰기
조직 서비스의 xRM 메시지
검색 서비스의 메시지
조직 서비스의 CRM 메시지
데이터 가져오기

© 2017 Microsoft. All rights reserved. 저작권 정보