Ne pas utiliser les types de demandes par lots dans les plug-ins et les activités de workflow

Catégorie : Utilisation, fiabilité, performance

Potentiel d’impact : Moyen

Symptômes

Les expériences utilisateur sont dégradées et des erreurs de délai d’attente peuvent se produire lorsque vous utilisez les types de demandes par lots dans les plug-ins et les activités de workflow qui se produisent au sein des opérations synchrones.

Les classes de demandes de message suivantes sont considérées comme des types de demandes par lots car elles effectuent des opérations sur plusieurs enregistrements dans une seule demande :

Conseils

Utilisez ces messages par lots dans les applications clientes pour effectuer des opérations sur plusieurs enregistrements. N’utilisez pas ces messages dans le code invoqué par Dataverse lors de l’exécution d’une autre opération : un plug-in ou un activité de workflow enregistré pour une étape synchrone.

Plus spécifiquement, utilisez-les dans les scénarios suivants :

Schémas problématiques

L’exemple suivant montre l’utilisation de ExecuteMultipleRequest dans le contexte d’un plug-in.

Avertissement

Ce scénario doit être évité.

public class ExecuteMultipleRequestInPlugin : IPlugin
{
    public void Execute(IServiceProvider serviceProvider)
    {
        IPluginExecutionContext context = (IPluginExecutionContext)serviceProvider.GetService(typeof(IPluginExecutionContext));
        IOrganizationServiceFactory factory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
        IOrganizationService service = factory.CreateOrganizationService(context.UserId);

        QueryExpression query = new QueryExpression("account")
        {
            ColumnSet = new ColumnSet("accountname", "createdon"),
        };

        //Obtain the results of previous QueryExpression
        EntityCollection results = service.RetrieveMultiple(query);

        if (results != null && results.Entities != null && results.Entities.Count > 0)
        {
            ExecuteMultipleRequest batch = new ExecuteMultipleRequest();
            foreach (Entity account in results.Entities)
            {
                account.Attributes["accountname"] += "_UPDATED";

                UpdateRequest updateRequest = new UpdateRequest();
                updateRequest.Target = account;

                batch.Requests.Add(updateRequest);
            }

            service.Execute(batch);
        }
        else return;

    }
}

Cet exemple comprend l’utilisation du type directement avec la méthode Execute. L’utilisation peut être n’importe où dans le contexte d’une exécution d’un plug-in ou d’activité de workflow. Il peut s’agir d’une méthode qui est contenue dans la même classe ou une classe distincte, également. Elle n’est pas limitée à être contenue directement dans la définition de la méthode Execute.

Informations supplémentaires

L’objectif du message ExecuteMultiple est de réduire les allers-retours entre le client et le serveur sur les connexions à haute latence. Les plug-ins s’exécutent directement dans les processus d’application ou à proximité une fois le bac à sable isolé, ce qui signifie que la latence est rarement un problème. Le code du plug-in doit être des opérations ciblées qui s’exécutent rapidement et réduisent les blocages pour éviter de dépasser les seuils de délai d’attente et garantir un système réactif pour les scénarios synchrones. Soumettez chaque demande directement au lieu de les regrouper et de les soumettre en une seule demande.

Par exemple : foreach (request in requests) service.Execute(request)

Côté serveur, les opérations incluses dans une demande par lots sont exécutées de manière séquentielle et ne sont pas effectuées en parallèle. C’est le cas même si la propriété ExecuteMultipleSettings.ReturnResponses est définie sur false. Les développeurs ont tendance à utiliser les demandes par lots de cette manière en sachant qu'elles permettent le traitement en parallèle. Les demandes par lots n’atteignent pas cet objectif.

Les personnes utilisent ExecuteTransactionRequest pour garantir que chaque opération est incluse dans une transaction. Cela est inutile dans une étape de plug-in synchrone car le plug-in est déjà en cours d’exécution dans le contexte d’une transaction de base de données, ce qui annule la nécessité d’utiliser le message ExecuteTransaction.

Voir aussi

Infrastructure d’événements
Limitations à l’exécution
Exécuter plusieurs requêtes à l’aide du SDK pour .NET
Exécuter des messages en une seule transaction de base de données

Notes

Pouvez-vous nous indiquer vos préférences de langue pour la documentation ? Répondez à un court questionnaire. (veuillez noter que ce questionnaire est en anglais)

Le questionnaire vous prendra environ sept minutes. Aucune donnée personnelle n’est collectée (déclaration de confidentialité).