Partager via


Conception de personnalisation évolutive : transactions de base de données

Note

Il s’agit du deuxième dans une série de sujets sur la personnalisation évolutive. Pour commencer au début, consultez La conception de personnalisation évolutive dans Microsoft Dataverse.

L’un des concepts les plus fondamentaux de la plupart des défis rencontrés ici est celui de la transaction de base de données. Dans Dataverse, la base de données est au cœur de presque toutes les demandes adressées au système et la cohérence des données de place est principalement appliquée.

  • Aucune opération de données Dataverse, qu'elle soit interne ou partie des personnalisations de code, ne fonctionne complètement isolée.
  • Toutes les opérations de données Dataverse interagissent avec les mêmes ressources de base de données, soit au niveau des données, soit au niveau de l’infrastructure, comme le processeur, la mémoire ou l’utilisation des E/S.
  • Pour vous protéger contre les modifications en conflit, chaque requête accepte des verrous sur les ressources à afficher ou à modifier.
  • Ces verrous sont pris dans une transaction et ne sont pas libérés tant que la transaction n’est pas validée ou abandonnée.

Conscience des transactions et du verrouillage

Une raison courante pour laquelle les problèmes peuvent se produire dans ce domaine est le manque de connaissance de la façon dont les personnalisations peuvent affecter les transactions.

Bien que les détails de cette opération soient au-delà de l’étendue de cet article, l’élément le plus simple à prendre en compte est que Dataverse interagit avec les données de sa base de données. SQL Server détermine les verrous appropriés pris par les transactions sur ces données, telles que :

  • Lors de la création d’un enregistrement, il génère un verrou d’écriture sur cet enregistrement.
  • Lors de la mise à jour d′un enregistrement, il place un verrou en écriture sur l′enregistrement.
  • Lorsqu′un verrou est placé sur une table ou un enregistrement, il est également placé sur tous les enregistrements d′index correspondants.

Toutefois, il est possible d’influencer l’étendue et la durée de ces verrous. Il est également possible d’indiquer à SQL Server qu’aucun verrou n’est requis pour certains scénarios.

Prenons l’exemple du verrouillage de base de données SQL Server et de l’impact des requêtes distinctes qui tentent d’accéder aux mêmes données. Dans l’exemple suivant, la création d’un compte a configuré une série de processus, certaines avec des plug-ins déclenchés dès que l’enregistrement est créé, et certains dans un flux de travail asynchrone associé lancé lors de la création.

L’exemple montre les conséquences lorsqu’un processus de mise à jour de compte a un traitement post-traitement complexe, tandis que d’autres activités interagissent également avec le même enregistrement de compte. Si un flux de travail asynchrone est traité pendant que la transaction de mise à jour du compte est toujours en cours, ce flux de travail peut être bloqué en attente d’obtenir un verrou de mise à jour pour modifier le même enregistrement de compte, qui est toujours verrouillé.

exemple de verrouillage et de transactions.

Il convient de noter que les transactions ne sont conservées qu’au cours de la durée de vie d’une demande particulière adressée à la plateforme. Les verrous ne sont pas conservés au niveau d’une session utilisateur ou pendant que les informations sont affichées dans l’interface utilisateur. Dès que la plateforme a terminé la demande, elle libère la connexion de base de données, la transaction associée et les verrous qu’elle a pris.

Blocage

Bien que le type de blocage dans l’exemple précédent puisse être inconvenient en soi, ce blocage peut également entraîner des conséquences plus graves lorsque vous considérez que Dataverse est une plateforme qui peut traiter des centaines d’actions simultanées. Bien que le maintenir d′un verrou sur un enregistrement de compte individuel peut avoir raisonnablement des implications limitées, que se passe-t-il lorsqu′une ressource est plus fortement contestée ?

Par exemple, lorsque chaque compte obtient un seul numéro de référence, cela peut aboutir au blocage d′une seule ressource effectuant le suivi des numéros de référence utilisés par chaque processus de création de compte. Comme décrit dans l’exemple de numérotation automatique, si un grand nombre de comptes sont générés en parallèle, les demandes qui se chevauchent doivent tous accéder à cette ressource de numérotation automatique et la bloquer jusqu’à ce qu’elles terminent leur action. Plus la durée de chaque processus de création de compte s'allonge, et plus il y a de demandes simultanées, plus le blocage est fréquent.

Bien que la première demande de saisie du verrou de ressource de numérotation automatique puisse être facilement exécutée, la seconde demande devra attendre que la première se termine avant de pouvoir contrôler quel est le prochain numéro de référence unique. La troisième demande doit attendre que les première et deuxième demandes soient terminées. Plus il y a de requêtes, plus le blocage dure longtemps. S'il y a suffisamment de requêtes et que chacune d'elles prend suffisamment de temps, ce délai peut retarder les requêtes suivantes jusqu'à ce qu'elles expirent, même si individuellement elles peuvent se terminer correctement.

exemple de blocage.

Libération du verrou

Il existe deux raisons principales pour lesquelles un verrou n’est pas libéré, mais qu’il est conservé tant que la transaction n’est pas terminée :

  • Le serveur de base de données conserve le verrou pour assurer la cohérence si la transaction effectue ultérieurement une autre demande de mise à jour de l’élément de données.
  • Le serveur de base de données doit également prendre en compte qu’une erreur ou une commande d’abandon émise ultérieurement peut entraîner l'annulation de l’intégralité de la transaction, de sorte qu’il doit conserver les verrous pendant toute la durée de vie de la transaction pour garantir la cohérence.

Il est important de reconnaître que même si votre processus peut avoir effectué des interactions avec un élément de données particulier, le verrou est conservé jusqu’à ce que l’intégralité de la transaction soit terminée et validée. Plus la transaction est étendue, plus le verrou est conservé, ce qui empêche les autres threads d’interagir avec ces données. Comme indiqué plus loin, cela inclut également des personnalisations connexes qui fonctionnent dans la même transaction et peuvent étendre considérablement la durée de vie des transactions telles que les flux de travail synchrones.

Dans l’exemple suivant, le verrou d’écriture sur une entité personnalisée dans le plug-in de pré-création d’un compte est verrouillé jusqu’à ce que toute logique liée à la création du compte soit terminée.

libération de verrou.

Erreurs intermittentes : minutage

Le comportement intermittent est un symptôme évident du blocage de l’activité simultanée. Si la répétition exacte de la même action réussit plus tard lorsqu’elle a échoué plus tôt, il existe une forte probabilité que l’erreur ou la lenteur ait été causée par un autre événement en même temps.

Il est important de réaliser que le débogage d’un problème implique souvent de supprimer la fonctionnalité incriminée au minimum. Toutefois, lorsque le problème se produit uniquement par intermittence, vous devrez peut-être examiner où l’action défaillante est en conflit avec une autre activité dans le système, et vous devez examiner les points de contention potentiels. Vous pouvez atténuer les conflits en optimisant un processus individuel ; toutefois, plus le temps de traitement est court, moins l’activité est en conflit avec d’autres processus.

Contrôle de transaction

Bien que dans la plupart des cas, la façon dont les transactions sont utilisées peut être laissée à la plateforme pour gérer, il existe des scénarios où la logique nécessaire est suffisamment complexe pour que la compréhension et l’influence sur les transactions soient nécessaires pour obtenir les résultats souhaités. Dataverse offre de nombreuses approches de personnalisation différentes qui ont un impact différent sur la façon dont les transactions sont utilisées.

Lorsque vous comprenez comment chaque type de personnalisation participe aux transactions de plateforme, vous pouvez modéliser des scénarios complexes efficacement dans Dataverse et prédire leur comportement.

Comme mentionné précédemment, une transaction est conservée uniquement pendant la durée de vie d’une demande adressée à la plateforme, ce n’est pas quelque chose qui est conservé une fois l’étape de la plateforme terminée. Cette durée limitée évite que les transactions soient détenues par un client externe pendant de longues périodes et bloquent d’autres activités de plateforme.

Le travail de la plateforme consiste à maintenir la cohérence tout au long du pipeline de transaction de la plateforme et, le cas échéant, permettre aux personnalisations de participer à cette même transaction.

Comment les applications basées sur des modèles utilisent des transactions

Avant de comprendre comment les personnalisations interagissent avec la plateforme, il est utile de comprendre comment les applications basées sur des modèles utilisent les demandes adressées à la plateforme et comment elles affectent l’utilisation des transactions.

Opération Descriptif
Formulaires (Retrieve) • Faible impact sur d’autres utilisations.
Créer • Effectue une demande de création via la plateforme
• Faible impact sur les autres activités, car un nouvel enregistrement ne devrait rencontrer aucun obstacle.
• Peut potentiellement bloquer les requêtes de verrou de toute la table jusqu′à ce qu′elle soit terminée.
• Souvent, il est possible de déclencher des actions connexes dans la personnalisation qui peuvent avoir un impact.
Update • Effectue une demande de mise à jour via la plateforme.
• Plus susceptible d’avoir des conflits. Un verrou de mise à jour bloque toute autre mise à jour de cet enregistrement.
• Déclenche souvent d’autres activités.
• Dans certains cas rares, un verrou de mise à jour peut bloquer un verrou de lecture. L’un des exemples où cela peut se produire est le moment où les métadonnées Dataverse sont modifiées : les lectures effectuées par une transaction de modification des métadonnées Dataverse sont bloquées par des verrous de mise à jour.
Afficher (RetrieveMultiple) • Faible impact sur d’autres utilisations.
• Les requêtes mal optimisées peuvent surcharger les ressources de la base de données et entraîner des expirations de délai.

Pipeline d’événements : étape de plateforme

Lorsqu’un pipeline d’événements est lancé, une transaction SQL est créée pour inclure l’étape de plateforme. Cela garantit que toutes les activités de base de données effectuées par la plateforme sont mises en place de manière cohérente. La transaction est créée au début du pipeline d’événements et validée ou annulée lorsque le traitement est terminé, selon le succès du traitement.

étape de plateforme du pipeline d′événements.

Demandes de personnalisation

Il est également possible de participer à la transaction initiée par la plateforme dans les personnalisations. Chaque type de personnalisation participe à des transactions d’une manière différente. Les sections suivantes décrivent chacune d’elles à leur tour.

Synchroniser les plug-ins (pré ou post-opération : dans le contexte de transaction)

Lorsque des plug-ins sont enregistrés pour un événement, ils peuvent être enregistrés dans une étape d′PreOperation ou de PostOperation qui se trouve dans la transaction. Toutes les demandes de message du plug-in sont effectuées dans la transaction. Cela signifie que la durée de vie de la transaction, et de tous les verrous placés, sera prolongée.

Synchroniser les plug-ins (pré ou post-opération : dans le contexte de transaction).

Synchroniser les plug-ins (avant et après l’opération : dans le contexte de transaction)

Les modules complémentaires peuvent être enregistrés pour les étapes PreOperation et PostOperation. Dans ce cas, la transaction peut s’étendre encore plus, car elle s’étend du début du plug-in PreOperation jusqu’à la fin du plug-in PostOperation .

Synchroniser les plug-ins (avant et après l’opération : dans le contexte de transaction).

Plug-ins de synchronisation (PreValidation : contexte de transaction externe)

Un module peut également être enregistré pour agir en dehors de la transaction de plateforme en étant placé dans l'étape PreValidation.

Note

Elle ne crée pas sa propre transaction. Par conséquent, chaque demande de message dans le plug-in est traitée indépendamment dans la base de données.

Plug-ins de synchronisation (prévalidation : en dehors du contexte de transaction).

Ce scénario s’applique uniquement lorsque le PreValidation est appelé comme première étape d’un événement de pipeline. Même si le plug-in est inscrit à la phase PreValidation , il est possible qu’il participe à une transaction comme décrit dans la section suivante. Il ne peut pas être supposé qu’un plug-in PreValidation ne participe pas à une transaction, bien qu’il soit possible de vérifier à partir du contexte d’exécution s’il s’agit du cas.

Plug-ins de synchronisation (PreValidation : dans le contexte de transaction)

Le scénario associé se produit lorsqu’un plug-in PreValidation est inscrit, mais que l’événement de pipeline associé est déclenché par la demande de message à partir d’une transaction existante.

Comme le montre le diagramme suivant, la création d’un compte peut entraîner l’exécution initiale d’un plug-in PreValidation en dehors d’une transaction lorsque la création initiale est effectuée. Si, dans le cadre du plug-in de validation, la demande de message est faite pour créer un compte enfant associé car ce deuxième pipeline d′événements est initialisé depuis pipeline parent, il participera à la même transaction.

Dans ce cas, le plug-in PreValidation découvre qu’une transaction existe déjà et participe ainsi à cette transaction même si elle est inscrite à la phase De PréValidation .

Plug-ins de synchronisation (PreValidation : dans le contexte de transaction).

Comme mentionné précédemment, le plug-in peut vérifier le contexte d’exécution de la IsInTransaction propriété, ce qui indique si ce plug-in s’exécute dans une transaction ou non.

Plug-ins asynchrones

Un plug-in peut également être inscrit pour agir de manière asynchrone. Dans ce cas, le plug-in agit également en dehors de la transaction de plateforme.

Note

Le plug-in ne crée pas sa propre transaction ; chaque demande de message dans le plug-in est traitée indépendamment.

Foo.

Résumé d′utilisation de transaction de plug-in

Pour résumer :

  • Les plug-ins synchrones participent généralement aux transactions.
  • Les plug-ins asynchrones ne participent jamais à une transaction de plateforme ; chaque requête est effectuée indépendamment.
  • Les plug-ins PreValidation ne créent pas de transaction, mais participent s’il en existe déjà une.
Événement Nom de la phase La transaction n’existe pas encore La transaction existe déjà
Pré-événement PreValidation Aucune transaction n’est créée. Ne participe pas à la transaction ; chaque requête utilise une transaction indépendante dans la base de données Participe à la transaction existante
Pré-événement Préopération Participe à la transaction existante Participe à la transaction existante
Après l'événement PostOpération Participe à la transaction existante Participe à la transaction existante
Async N/A Aucune transaction n’est créée. Ne participe pas à la transaction ; chaque requête utilise une transaction indépendante dans la base de données N/A

Flux de travail synchrones

Du point de vue des transactions, les flux de travail synchrones agissent comme des plug-ins de pré/post-opération. Ils agissent donc dans la transaction de pipeline de plateforme et peuvent avoir le même effet sur la longueur de la transaction globale.

Flux de travail synchrones.

Flux de travail asynchrones

Les flux de travail asynchrones sont déclenchés en dehors de la transaction de plateforme.

Note

Le flux de travail ne crée pas non plus sa propre transaction. Par conséquent, chaque demande de message au sein du flux de travail est traitée indépendamment.

Le diagramme suivant montre le flux de travail asynchrone agissant en dehors de la transaction de plateforme et chaque étape qui lance sa propre transaction indépendante.

Flux de travail asynchrones.

Activité de flux de travail personnalisée

Les activités de workflow personnalisées agissent dans le contexte du workflow parent.

  • Flux de travail de synchronisation : agit à l'intérieur de la transaction
  • Flux de travail asynchrone : agit en dehors de la transaction

Le diagramme suivant montre les activités personnalisées qui agissent d’abord dans un flux de travail synchrone, puis dans un flux de travail asynchrone.

Activité de flux de travail personnalisée.

Actions personnalisées

Les actions personnalisées peuvent créer leurs propres transactions. Il s’agit d’une fonctionnalité clé. Une action personnalisée peut créer une transaction distincte en dehors de l’étape de la plateforme, selon qu’elle est configurée pour activer le Rollback.

  • Activer la restauration défini
    • Si elle est appelée via une demande de message d′un plug-in s′exécutant dans la transaction, et que Activer la restauration est définie, l′action personnalisée agira au sein de la transaction existante.
    • Sinon, l'action personnalisée crée une nouvelle transaction et s'exécute à l'intérieur de celle-ci.
  • Activation du retour en arrière non configurée
    • L'action personnalisée n'opérera pas au sein d'une transaction.

actions personnalisées.

Demandes de service web

Lorsque des requêtes sont effectuées en externe via des services web, un pipeline est créé et la gestion des transactions au sein du pipeline se produit comme indiqué précédemment, mais une transaction n’est pas conservée une fois la réponse retournée. Étant donné que la durée jusqu’à la prochaine requête est inconnue, la plateforme n’autorise pas le verrouillage des ressources qui bloquerait les autres activités.

Lorsque plusieurs requêtes sont effectuées dans un plug-in à l’aide du même contexte d’exécution, il s’agit du contexte d’exécution courant qui gère la référence de transaction et dans les plug-ins synchrones garantit que chaque requête est effectuée dans la même transaction. La possibilité de maintenir un contexte d’exécution entre les requêtes n’est pas disponible en dehors des plug-ins et, par conséquent, une transaction ne peut pas être conservée entre les requêtes distinctes effectuées en externe.

Il existe deux messages spéciaux où plusieurs actions peuvent être transmises à la plateforme Dataverse dans le cadre d’une demande de service web unique.

Message Descriptif
ExecuteMultiple Cela permet à plusieurs actions indépendantes d’être passées dans la même demande de service web. Chacune de ces requêtes est effectuée indépendamment au sein de la plateforme afin qu’il n’y ait aucun contexte de transaction détenu entre les requêtes.
ExecuteTransaction Cela permet à plusieurs actions d’être traitées dans la même transaction de base de données, de la même façon que plusieurs demandes de message effectuées à partir d’un plug-in synchrone.

Cette capacité aurait également des implications similaires à plusieurs demandes de messages ; autrement dit, si chaque action prend beaucoup de temps (par exemple en effectuant des requêtes coûteuses ou en déclenchant une longue chaîne de plug-ins ou de flux de travail synchrones connexes), cela peut entraîner des problèmes de blocage dans la plateforme plus large.

Requêtes d’API web (OData) dans les plug-ins

N’utilisez pas de requêtes d’API web (OData) au sein d’un plug-in dans la même organisation que le plug-in. Utilisez toujours les IOrganizationService méthodes. Cela permet de transmettre le contexte de transaction afin que l'opération puisse participer à la transaction du pipeline.

Étapes suivantes

En plus des transactions de base de données, il est important d’apprécier l’impact de plusieurs opérations de données simultanées sur le système. Plus d’informations : Conception de personnalisation évolutive : problèmes de concurrence