大量データ負荷でパフォーマンスを向上させる ExecuteMultiple を使用する

 

公開日: 2017年1月

対象: Dynamics 365 (online)、Dynamics 365 (on-premises)、Dynamics CRM 2016、Dynamics CRM Online

特に、インターネットの待ち時間が最大の制限要因になる場合のある Microsoft Dynamics 365 (オンライン) の場合、Microsoft Dynamics 365 (オンラインおよび設置型) でより高い効率の一括メッセージ渡しシナリオをサポートするため 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に設定されます。

しかし、エラーが返された場合、falseResponses のコレクションは空ではなくなります。 エラーが返された場合、フォールトを返した処理された各要求のコレクションに1つの応答アイテムがあり、Faultは発生した実際のフォールトに設定されます。

たとえば、6つの要求を含み、その3番目と5番目の要求がフォールトを返す要求コレクションの場合、次の表にはResponses のコレクションの内容を示します。

設定

応答コレクションの内容

ContinueOnError=true、ReturnResponses=true

6 種類の応答アイテム: 2 種類には1つの値に設定した Fault があります。

ContinueOnError=false、ReturnResponses=true

3 種類の応答アイテム: 1 種類には1つの値に設定した Fault があります。

ContinueOnError=true、ReturnResponses=false

2 種類の応答アイテム: 2 種類には1つの値に設定した Fault があります。

ContinueOnError=false、ReturnResponses=false

1 種類の応答アイテム: 1 種類には1つの値に設定した Fault があります。

応答アイテムの RequestIndex パラメーターは、応答が関連付けられている要求の、先頭がゼロで始まるシーケンス番号を示します。 前の例では、3 番目の要求には 2 の要求インデックスがあります。

ランタイムの制限

以下のリストで示すように、ExecuteMultipleRequest の使用に関する、いくつかの制限があります。

  • 再帰は許可されません- ExecuteMultipleRequest では ExecuteMultipleRequestを起動できません。 要求コレクションで見つかる ExecuteMultipleRequest は、その要求アイテムに関するエラーを生成します。

  • 最大バッチ サイズ – 要求コレクションに追加できる要求の数には制限があります。 この制限を超えると、最初の要求が実行される前にフォールトがスローされます。Microsoft Dynamics 365展開に最大数を設定できますが、1000 個の制限が一般的です。 この上限の展開設定は、BatchSizeです。

  • 同時呼び出しの調整 – Microsoft Dynamics 365 (オンライン) の場合、組織ごとに ExecuteMultipleRequest 2 人の同時実行の制限があります。 この制限を超えると、最初の要求が実行される前に "サーバー ビジー" フォールトがスローされます。 設置型展開の場合、既定では調整が有効ではありません。 この上限の展開設定は、ExecuteAsyncPerOrgMaxConnectionsPerServerです。

    ヒント

    任意の Dynamics 365 展開の場合、展開管理者はスロットリングの限界の設定、または変更できます。

バッチ サイズのフォールトの処理

入力要求コレクションが最大サイズ バッチを超えた場合に何をすればよいですか。 コードでは、展開管理者ロールを持つアカウントで実行されていない限り、展開 web サービスを通して、最大サイズ バッチを直接を問い合わせることができません。

幸いにも、使用できる別の方法があります。 入力 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
組織サービスを使用したデータまたはメタデータの読み取りと書き込み
組織サービスにおける xRM メッセージ
探索サービスのメッセージ
組織サービスにおける Dynamics 365 メッセージ
データのインポート

Microsoft Dynamics 365

© 2017 Microsoft. All rights reserved. 著作権