プラグインのトラブルシューティング

この記事には、プラグイン実行が原因で発生する可能性があるエラーと、その修正方法に関する情報が含まれます。

エラー: サンドボックス ワーカー プロセスがクラッシュしました

エラー コード: -2147204723
エラー メッセージ: The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.

このエラーは、プラグイン コードを実行しているワーカー プロセスがクラッシュしたことを意味します。 クラッシュした理由はプラグインである可能性がありますが、組織で同時に実行されている別のプラグインである可能性もあります。 プロセスがクラッシュしたため、クラッシュした理由に関する具体的な情報を抽出することができません。 しかし、事後にクラッシュ ダンプからのデータを調べたところ、これは通常、以下の 4 つの理由のいずれが原因で発生することがわかりました:

  • プラグインでハンドルされない例外
  • プラグインの Stack Overflow エラー
  • スレッドを使用して、スレッド代理人で try/catch を使用せずに作業をキューに入れます
  • ワーカー プロセスがメモリ制限に達しました

プラグインでハンドルされない例外

プラグインで例外を処理するで述べた通り、プラグインを作成するときは、失敗する可能性のある操作を予測し、それらを try-catch ブロックでラップするようにしてください。 エラーが発生した場合は、InvalidPluginExecutionException を使って、ユーザーにとって意味のあるエラーで操作を正常に終了します。

この一般的なシナリオでは、HttpClient.SendAsync メソッド または HttpClient.GetAsync メソッドを使用します。これは、タスクを返す非同期操作です。 コードを同期する必要があるプラグインでこれを機能させるために、Task<TResult>.Result Property を使用することができます。 エラーが発生した場合、AggregateException が返されます。これにより複数の障害が 1 つの例外に統合され、処理が困難になる可能性があります。 より優れた方法として、Task<TResult>.GetAwaiter().GetResult() を使用できます。これは、失敗の原因となった特定のエラーとして結果を反映します。

次の例は、HttpClient.GetAsync Method を使用して例外とアウトバウンド コールを管理する正しい方法を示しています。 このプラグインは、登録されているステップの安全でない構成に設定されている URL の応答テキストを取得しようとします。

using Microsoft.Xrm.Sdk;
using System;
using System.Net.Http;

namespace ErrorRepro
{
    public class AsyncError : IPlugin
    {
        private readonly string webAddress;

        public AsyncError(string unsecureConfig)
        {
            if (string.IsNullOrEmpty(unsecureConfig)) {
                throw new InvalidPluginExecutionException("The ErrorRepro.AsyncError plug-in requires that a Url be set in the unsecure configuration for the step registration.");
            }
            webAddress = unsecureConfig;

        }

        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
            (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            tracingService.Trace($"Starting ErrorRepro.AsyncError");
            tracingService.Trace($"Sending web request to {webAddress}");

            try
            {
                string responseText = GetWebResponse(webAddress, tracingService);
                tracingService.Trace($"Result: {responseText.Substring(0, 100)}");
            }
            catch (Exception ex)
            {
                tracingService.Trace($"Error: ErrorRepro.AsyncError {ex.Message}");
                throw new InvalidPluginExecutionException(ex.Message);
            }
            tracingService.Trace($"Ending ErrorRepro.AsyncError");
        }

        //Gets the text response of an outbound web service call
        public string GetWebResponse(string webAddress, ITracingService tracingService)
        {
            try
            {
                using (HttpClient client = new HttpClient())
                {
                    client.Timeout = TimeSpan.FromMilliseconds(15000); //15 seconds
                    client.DefaultRequestHeaders.ConnectionClose = true; //Set KeepAlive to false

                    HttpResponseMessage response = client.GetAsync(webAddress).GetAwaiter().GetResult(); //Make sure it is synchronous
                    response.EnsureSuccessStatusCode();

                    tracingService.Trace($"ErrorRepro.AsyncError.GetWebResponse succeeded.");

                    string responseContent = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); //Make sure it is synchronous

                    tracingService.Trace($"ErrorRepro.AsyncError.GetWebResponse responseContent parsed successfully.");

                    return responseContent;

                }
            }
            catch (Exception ex)
            {
                //Capture the inner exception message if it exists.
                // It should have a more specific detail.
                string innerExceptionMessage = string.Empty;
                if (ex.InnerException != null) {
                    innerExceptionMessage = ex.InnerException.Message;
                }

                tracingService.Trace($"Error in ErrorRepro.AsyncError : {ex.Message} InnerException: {innerExceptionMessage}");
                if (!string.IsNullOrEmpty(innerExceptionMessage))
                {
                    throw new Exception($"A call to an external web service failed. {innerExceptionMessage}", ex);
                }

                throw new Exception("A call to an external web service failed.", ex);
            }
        }
    }
}

プラグインの Stack Overflow エラー

このタイプのエラーは、プラグイン コードに変更を加えた直後に最も頻繁に発生します。 一部の人々は、独自の基本クラスのセットを使用して、開発エクスペリエンスを合理化します。 これらのエラーは、特定のプラグインが依存する基本クラスへの変更に起因する場合があります。

たとえば、終了条件のない再帰呼び出し、またはすべてのシナリオをカバーしていない終了条件は、この原因となる可能性があります。 詳細: StackOverflowException クラス > 備考

プラグインに最近適用されたコードの変更、およびプラグイン コードが依存するその他のコードをレビューする必要があります。

次のプラグイン コードは、制限のない再帰呼び出しが原因で StackOverflowException を引き起こします。 トレースを使用し、エラーをキャプチャしようとしても、トレースを処理するワーカー プロセスが終了したため、トレースもエラーも返されません。

using Microsoft.Xrm.Sdk;
using System;

namespace ErrorRepro
{
    public class SOError : IPlugin
    {
        public void Execute(IServiceProvider serviceProvider)
        {
            ITracingService tracingService =
           (ITracingService)serviceProvider.GetService(typeof(ITracingService));

            tracingService.Trace($"Starting ErrorRepro.SOError");

            try
            {
                tracingService.Trace($"Calling RecursiveMethodWithNoLimit to trigger StackOverflow error.");

                RecursiveMethodWithNoLimit(tracingService); //StackOverflowException occurs here.
            }
            catch (Exception ex)
            {
                //This trace will not be written
                tracingService.Trace($"Error in ErrorRepro.SOError {ex.Message}");

                //This error will never be thrown
                throw new InvalidPluginExecutionException($"Error in ErrorRepro.SOError. {ex.Message}");
            }

            //This trace will never be written
            tracingService.Trace($"Ending ErrorRepro.SOError");
        }

        public static void RecursiveMethodWithNoLimit(ITracingService tracingService)
        {
            tracingService.Trace($"Starting ErrorRepro.SOError.RecursiveMethodWithNoLimit");

            RecursiveMethodWithNoLimit(tracingService);

            tracingService.Trace($"Ending ErrorRepro.SOError.RecursiveMethodWithNoLimit");
        }
    }
}

上記のプラグイン コードを同期プラグインで使用すると、Web API から次のエラーが返されます。

{
    "error": {
        "code": "0x8004418d",
        "message": "The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.\r\nSystem.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.\r\n   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #8503641A",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionSourceKey": "Plugin/ErrorRepro.SOError, ErrorRepro, Version=1.0.0.0, Culture=neutral, PublicKeyToken=c2bee3e550ec0851",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepKey": "d5958631-b87e-eb11-a812-000d3a4f50a7",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiDepthKey": "1",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiActivityIdKey": "a3028bda-73c2-4eef-bcb5-157c5a4c323e",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiPluginSolutionNameKey": "Active",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiStepSolutionNameKey": "Active",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionCategory": "SystemFailure",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionMesageName": "SandboxWorkerNotAvailable",
        "@Microsoft.PowerApps.CDS.ErrorDetails.ApiExceptionHttpStatusCode": "500",
        "@Microsoft.PowerApps.CDS.HelpLink": "http://go.microsoft.com/fwlink/?LinkID=398563&error=Microsoft.Crm.CrmException%3a8004418d&client=platform",
        "@Microsoft.PowerApps.CDS.TraceText": "\r\n[ErrorRepro: ErrorRepro.SOError]\r\n[d5958631-b87e-eb11-a812-000d3a4f50a7: ErrorRepro.SOError: Create of account]\r\n\r\n",
        "@Microsoft.PowerApps.CDS.InnerError.Message": "The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.\r\nSystem.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.\r\n   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #8503641A"
    }
}

これは、このエラーがプラグイン トレース ログに記録される方法です。

Unhandled exception: 
Exception type: System.ServiceModel.FaultException`1[Microsoft.Xrm.Sdk.OrganizationServiceFault]
Message: The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64& wcfExecInMs, Int64& initializeInMs, Int64& trackCallInMs, Int64& trackGoodReturnInMs, Int64& waitInMs, Int64& taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #4BC22433Detail: 
<OrganizationServiceFault xmlns:i="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://schemas.microsoft.com/xrm/2011/Contracts">
  <ActivityId>48c5818e-4912-42f0-b1b6-e3bbe7ae013d</ActivityId>
  <ErrorCode>-2147204723</ErrorCode>
  <ErrorDetails xmlns:d2p1="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
  <HelpLink i:nil="true" />
  <Message>The plug-in execution failed because the Sandbox Worker process crashed. This is typically due to an error in the plug-in code.
System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64&amp; wcfExecInMs, Int64&amp; initializeInMs, Int64&amp; trackCallInMs, Int64&amp; trackGoodReturnInMs, Int64&amp; waitInMs, Int64&amp; taskStartDelay) +0x330: Microsoft Dynamics CRM has experienced an error. Reference number for administrators or support: #4BC22433</Message>
  <Timestamp>2021-03-06T22:14:22.0629638Z</Timestamp>
  <ExceptionRetriable>false</ExceptionRetriable>
  <ExceptionSource>WorkerCommunication</ExceptionSource>
  <InnerFault i:nil="true" />
  <OriginalException>System.ServiceModel.CommunicationException: The server did not provide a meaningful reply; this might be caused by a contract mismatch, a premature session shutdown or an internal server error.

Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.Call(String action, Boolean oneway, ProxyOperationRuntime operation, Object[] ins, Object[] outs, TimeSpan timeout)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at Microsoft.Crm.Sandbox.SandboxWorkerProcess.Execute(SandboxCallInfo callInfo, SandboxPluginExecutionContext requestContext, Guid pluginAssemblyId, Int32 sourceHash, String assemblyName, Guid pluginTypeId, String pluginTypeName, String pluginConfiguration, String pluginSecureConfig, Boolean returnTraceInfo, Int64&amp; wcfExecInMs, Int64&amp; initializeInMs, Int64&amp; trackCallInMs, Int64&amp; trackGoodReturnInMs, Int64&amp; waitInMs, Int64&amp; taskStartDelay)</OriginalException>
  <TraceText i:nil="true" />
</OrganizationServiceFault>

スレッドを使用して、スレッド代理人で try/catch を使用せずに作業をキューに入れます

プラグインで並列実行パターンを使用しないでください。これは、このベストプラクティスの記事: プラグインおよびワークフロー アクティビティ内で並列実行を使用しないでくださいで喚起されています。 これらのパターンを使用すると、同期プラグインでのトランザクションの管理で問題が発生する可能性があります。 ただし、これらのパターンを使用しないもう 1 つの理由は、スレッド デリゲートの try/catch ブロックの外部で行われた作業は、ワーカープロセスをクラッシュさせる可能性があるためです。

ワーカー プロセスがメモリ制限に達しました

各ワーカー プロセスのメモリは有限です。 大量のデータを含む複数の同時操作が使用可能なメモリを超え、プロセス ワーカーがクラッシュする可能性がある状況があります。

ファイル データが含まれる RetrieveMultiple

この場合の一般的なシナリオは、要求にファイル データが含まれる RetrieveMultiple 操作に対してプラグインが実行される場合です。 たとえば、添付ファイルを含むメールを取得する場合などです。 このようなクエリで返される可能性のあるデータの量は予測できません。これは、メールが任意の数の添付ファイルに関連付けられている可能性があり、添付ファイル自体のサイズが異なる可能性があるためです。

同様の性質の複数のリクエストが同時に実行されている場合、必要なメモリの量が非常に大きくなります。 上限を超えると、プロセスがクラッシュします。 これを防ぐための鍵は、関連する添付ファイルを持つエンティティを含む RetrieveMultiple クエリを制限することです。 RetrieveMultiple を使用してレコードを取得しますが、ただし、個別の Retrieve 操作を使って、必要に応じて関連ファイルを取得します。

メモリ リーク

あまり一般的ではないシナリオは、プラグインのコードのメモリがリークしている場合です。 これは、プラグインがステートレスとして記述されていない場合に発生する可能性があります。これは、別のベストプラクティス: IPlugin 実装をステートレスとして開発するです。 プラグインがステートレスではなく、配列などのステートフル プロパティにデータを継続的に追加しようとする場合。 データの量は、使用可能なすべてのメモリを使用するところまで増加します。

トランザクション エラー

トランザクションに関連する 2 種類の一般的なエラーがあります。

エラー コード: -2146893812
エラー メッセージ: ISV code reduced the open transaction count. Custom plug-ins should not catch exceptions from OrganizationService calls and continue processing.

エラー コード: -2147220911
エラー メッセージ: There is no active transaction. This error is usually caused by custom plug-ins that ignore errors from service calls and continue processing.

注意

上位エラーが最近追加されました。 これは、問題を含むプラグイン内のコンテキスト内ですぐに発生します。 下位エラーは、引き続きさまざまな状況で発生する可能性があります (通常はユーザー定義ワークフロー活動が関係する状況)。 別のプラグインの問題が原因の可能性があります。

このメッセージを理解するには、同期プラグイン内でデータ操作に関連したエラーが発生した場合に、操作全体のトランザクションが終了することを認識する必要があります。

詳細: Microsoft Dataverseで拡張可能なカスタマイズ設計

最も一般的な原因は、開発者が成功する可能性がある操作を試行できると単に信じることで、失敗したとき、その操作を try / catch ブロックでラップして、エラーを吸収しようとします。

これはクライアント アプリケーションでは有効ですが、プラグイン実行中にはデータ操作の失敗によってトランザクション全体がロール バックされます。 エラーを吸収できないので、必ず InvalidPluginExecutionException を返す必要があります。

エラー: SQL エラー: 実行タイムアウト期限切れ

エラー コード: -2147204783
エラー メッセージ: Sql error: 'Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding.'

SQL タイムアウト エラーの発生には様々な理由があります。

ブロック

ブロックは SQL タイムアウト エラーの最も一般的な原因であり、これは操作が別の SQL トランザクションがロックしたリソースを待っています。 このエラーは、システムがデータの整合性とユーザーのパフォーマンスに影響を与える長時間の要求から保護しているためです。

ブロックは並行した他の操作が原因の可能性があります。 あなたのコードはテスト環境では独立して問題なく動作するにも関わらず、複数のユーザーがプラグインのロジックを起動した場合にのみ発生する状況の影響を受ける場合があります。

プラグインを書くときは、スケーラブルなカスタマイズの設計方法を理解することが重要です。 詳細: Dataverse で拡張可能なカスタマイズ設計

カスケード操作

レコードの割り当てや削除などプラグインで行う特定の操作が、関連レコードのカスケード操作を開始することがあります。 これらのアクションが関連レコードにロックを適用し、その後のデータ操作をブロックして SQL タイムアウトを発生させる可能性があります。

プラグインのデータ操作でこれらのカスケード操作の影響を考慮する必要があります。 詳細: テーブル関係の動作

これらの動作は環境によって異なる方法で構成できるため、環境が同じように設定されていない限り動作を再現するのは困難です。

新しいテーブルのインデックス

プラグインが最近作成されたテーブルや列を使用して操作を実行している場合、インデックスを管理する Azure SQL 機能のいくつかは数日後に違いが生じる可能性があります。

ユーザー特権によるエラー

クライアント アプリケーションではユーザーが実行を許可されていないコマンドを無効にできます。 プラグインにはこれがありません。 あなたのコードは、呼び出し元のユーザーが実行する特権を持っていない自動化を含んでいる可能性があります。

ユーザーに ユーザーのコンテキストで実行 値を設定することで、正しい特権を確かに持っているユーザーのコンテキストで実行するようプラグインを登録できます。 または他のユーザーに偽装して操作を実行できます。 詳細:

エラー: コンテキストをサンドボックスに送信するとき Message のサイズが超過しました

エラー コード: -2147220970
エラー メッセージ: Message size exceeded when sending context to Sandbox. Message size: ### Mb

このエラーは、Message ペイロードが 116.85 MB を大きく超え、かつプラグインがメッセージに登録されている場合に発生します。 エラー Message には、エラーを引き起こしたペイロードのサイズが含まれています。

この制限はアプリケーションを実行しているユーザーが、リソースの制約に基づいて互いに干渉できないようにします。 この制限は、Dataverse プラットフォームの可用性およびパフォーマンス特性に対する脅威となる、並外れて大きな Message ペイロードに対する一定レベルの保護を与えるのに役立ちます。

116.85 MB は、このサポート案件では極端に大きなサイズといえます。 この案件が発生する可能性が高い状況は、大規模なバイナリ ファイルを含む複数の関連するレコードを持つレコードを回収するときです。

このエラーが表示された場合、次のように対応できます:

  1. Message に対するプラグインを削除します。 Message に登録されたプラグインが無い場合は、操作は失敗なく実行できます。
  2. カスタム クライアントでエラーが発生した場合、1 つの操作で作業を行うことがないようにコードを変更できます。 その代わり、より小さいパーツのデータを回復するためのコードを記述します。

エラー: 付与されたキーは、ディクショナリにありませんでした

Dataverse では、多くの場合、キーおよび値のコレクションを表す抽象 DataCollection<TKey,TValue> クラスから派生したクラスが使用されます。 たとえば、プラグインでIExecutionContextInputParameters プロパティは DataCollection<TKey,TValue> クラスから派生した ParameterCollection です。 これらのクラスは基本的に、キー名を使用して特定の値にアクセスするディクショナリ オブジェクトです。

エラー コード

このエラーは、コードのキー値がコレクションに存在しない場合に発生します。 これは、プラットフォーム エラーではなく、ランタイム エラーです。 このエラーがプラグイン内で発生するとき、エラー コードはエラーがキャッチされたかどうかによって異なります。

プラグインでの例外処理で説明されているように、開発者が例外をキャッチしてInvalidPluginExecutionExceptionが返された場合、次のエラーが返されます。

エラー コード: -2147220891
エラー メッセージ: ISV code aborted the operation.

ただし、このエラーに関しては、開発者がコンポーネントを適切にキャッチせず、次のエラーが共通で返されます:

エラー コード: -2147220956
エラー メッセージ: An unexpected error occurred from ISV code.

注意

「ISV」は独立系ソフトウェア ベンダーを意味します。

原因

このエラーは、設計時によく発生し、つづりの間違いまたは正しくないケーシングの使用が原因です。 キー値は、大文字と小文字が区別されます。

実行時のエラーは、開発者が値が存在しないときに存在していると仮定することに起因する場合が多くあります。 たとえば、テーブルの更新用に登録されたプラグインには、変更されるような値のみが Entity.Attributes に含まれます の値を使用します。

防止

このエラーを防ぐには、キーの存在を確認後にそれを使用して値にアクセスする必要があります。

たとえば、テーブル列にアクセスする場合は、Entityを次のように使用できます。Contains(String) 次のコードに示されるように、列がテーブルに存在するかどうかを確認する方法。

// Obtain the execution context from the service provider.  
IPluginExecutionContext context = (IPluginExecutionContext)
    serviceProvider.GetService(typeof(IPluginExecutionContext));

// The InputParameters collection contains all the data passed in the message request.  
if (context.InputParameters.Contains("Target") &&
    context.InputParameters["Target"] is Entity)
    {
    // Obtain the target entity from the input parameters.  
    Entity entity = (Entity)context.InputParameters["Target"];

    //Check whether the name attribute exists.
    if(entity.Contains("name"))
    {
        string name = entity["name"];
    }

一部の開発者はEntityを使用します。GetAttributeValue<T>(String) テーブル列にアクセスするときにこのエラーを回避するための方法で、この方法は、列が存在しないときにこの種類の規定値を返すことに注意してください。 既定値が null の場合は、適切に機能します。 しかし、DateTime でそうであるように、既定値が null を返さない場合は、返された値は null というよりも 1/1/0001 00:00 になります。

エラー: 現在のトランザクションにすでに設定されているものとは異なる分離レベルでトランザクションを開始することはできません

エラー コード: -2147220989
エラー メッセージ: You cannot start a transaction with a different isolation level than is already set on the current transaction

プラグインは、ビジネス ロジックをサポートすることを目的としています。 同期プラグイン内のデータ スキーマの一部の変更はサポートされていません。 これらの操作には時間がかかることが多く、アプリケーションで使用されるキャッシュされたメタデータが同期されなくなる可能性があります。ただし、これらの操作は、非同期で実行するように登録されたプラグイン ステップで実行できます。

注意

ドキュメントの言語設定についてお聞かせください。 簡単な調査を行います。 (この調査は英語です)

この調査には約 7 分かかります。 個人データは収集されません (プライバシー ステートメント)。