Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Hinweis
Dies ist die zweite in einer Reihe von Themen zum skalierbaren Anpassungsdesign. Informationen zu Beginn finden Sie unter "Skalierbares Anpassungsdesign" in Microsoft Dataverse.
Eines der grundlegenden Konzepte hinter vielen der Herausforderungen, die hier auftreten, ist das der Datenbanktransaktion. In Dataverse steht die Datenbank im Zentrum fast aller Anfragen an das System, und dort wird in erster Linie die Datenkonsistenz durchgesetzt.
- Keine Dataverse-Datenvorgänge, entweder interne oder Teil von Codeanpassungen, funktionieren vollständig isoliert.
- Alle Dataverse-Datenvorgänge interagieren mit den gleichen Datenbankressourcen, entweder auf Datenebene oder auf Infrastrukturebene wie Prozessor, Arbeitsspeicher oder E/A-Nutzung.
- Zum Schutz vor widersprüchlichen Änderungen übernimmt jede Anforderung Sperrungen für Ressourcen, die angezeigt oder geändert werden sollen.
- Diese Sperren werden innerhalb einer Transaktion gesetzt und erst freigegeben, wenn die Transaktion bestätigt oder abgebrochen wird.
Transaktions- und Sperrbewusstsein
Ein häufiger Grund dafür, dass Probleme in diesem Bereich auftreten können, ist der Mangel an Bewusstsein dafür, wie Anpassungen Transaktionen beeinflussen können.
Obwohl die Details dazu über den Umfang dieses Artikels hinausgehen, ist das einfachste Zu berücksichtigende Element, dass Dataverse mit Daten in seiner Datenbank interagiert. SQL Server bestimmt die entsprechenden Sperren, die von Transaktionen für diese Daten verwendet werden, wie z. B.:
- Beim Erstellen eines Datensatzes wird eine Schreibsperre für diesen Datensatz generiert.
- Beim Aktualisieren eines Datensatzes wird eine Schreibsperre gegen den Datensatz verhängt.
- Wenn eine Sperre gegen eine Tabelle oder einen Datensatz verhängt wird, wird sie auch gegen entsprechende Indexsätze verhängt.
Es ist jedoch möglich, den Umfang und die Dauer dieser Sperren zu beeinflussen. Es ist auch möglich, sql Server anzugeben, dass für bestimmte Szenarien keine Sperre erforderlich ist.
Betrachten wir die SQL Server-Datenbanksperre und die Auswirkungen separater Anforderungen, die versuchen, auf dieselben Daten zuzugreifen. Im folgenden Beispiel hat das Erstellen eines Kontos eine Reihe von Prozessen eingerichtet, einige mit Plug-Ins, die ausgelöst werden, sobald der Datensatz erstellt wird, und einige in einem zugehörigen asynchronen Workflow, der beim Erstellen initiiert wird.
Das Beispiel zeigt die Folgen, wenn ein Kontoaktualisierungsprozess komplexe Nachbearbeitungen aufweist, während andere Aktivitäten auch mit demselben Kontodatensatz interagieren. Wenn ein asynchroner Workflow verarbeitet wird, während die Kontoaktualisierungstransaktion noch ausgeführt wird, kann dieser Workflow blockiert werden, um eine Aktualisierungssperre zu erhalten, um denselben Kontodatensatz zu ändern, der noch gesperrt ist.
Es ist darauf hinzuweisen, dass Transaktionen nur innerhalb der Lebensdauer einer bestimmten Anforderung an die Plattform gehalten werden. Sperren werden nicht auf Benutzersitzungsebene gehalten oder während Informationen auf der Benutzeroberfläche angezeigt werden. Sobald die Plattform die Anforderung abgeschlossen hat, gibt sie die Datenbankverbindung, die zugehörige Transaktion und alle Sperren frei, die sie gesetzt hat.
Blockierung
Während die Art der Blockierung im vorherigen Beispiel an sich unpraktisch sein kann, kann diese Blockierung auch zu schwerwiegenderen Folgen führen, wenn Sie bedenken, dass Dataverse eine Plattform ist, die Hunderte gleichzeitiger Aktionen verarbeiten kann. Während das Halten einer Sperre für ein einzelnes Konto vernünftigerweise begrenzte Folgen haben kann, was geschieht, wenn eine Ressource stärker umkämpft ist?
Wenn beispielsweise jedem Konto eine eindeutige Referenznummer zugewiesen wird, kann dies dazu führen, dass eine einzelne Ressource, die die genutzten Referenznummern nachverfolgt, durch jeden Kontoerstellungsprozess blockiert wird. Wie im Beispiel der automatischen Nummerierung beschrieben, müssen alle überlappende Anfragen, wenn viele Konten parallel generiert werden, auf diese automatische Nummerierungsressource zugreifen und sie blockieren, bis sie ihre Aktion abgeschlossen haben. Je länger jeder Kontoerstellungsprozess dauert und je mehr gleichzeitige Anforderungen vorhanden sind, desto mehr Blockierung tritt auf.
Während die erste Anforderung, die automatische Ressourcensperre zu greifen, leicht abgeschlossen werden kann, muss die zweite Anforderung warten, bis die erste abgeschlossen ist, bevor sie überprüfen kann, was die nächste eindeutige Referenznummer ist. Die dritte Anforderung muss auf den Abschluss der ersten und zweiten Anforderung warten. Je mehr Anforderungen vorhanden sind, desto länger dauert die Blockierung an. Wenn es genügend Anforderungen gibt und jede Anforderung lange genug dauert, kann diese Verzögerung die späteren Anforderungen an den Punkt für einen Timeout bringen, auch wenn sie einzeln korrekt abgeschlossen werden können.
Sperrfreigabe
Es gibt zwei Hauptgründe, warum eine Sperre nicht freigegeben wird, aber solange gehalten wird, bis die Transaktion abgeschlossen ist:
- Der Datenbankserver hält die Sperre um Konsistenz zu gewährleisten, falls die Transaktion später eine weitere Anforderung zur Aktualisierung des Datenelements stellt.
- Der Datenbankserver muss auch zulassen, dass ein später ausgegebener Fehler- oder Abbruchbefehl dazu führen kann, dass die gesamte Transaktion zurückgerollt wird. Daher muss er die Sperren für die gesamte Lebensdauer der Transaktion sperren, um Konsistenz zu gewährleisten.
Es ist wichtig zu erkennen, dass die Sperre solange aufbewahrt wird, bis die gesamte Transaktion abgeschlossen und bestätigt wurde, obwohl Ihr Prozess alle Interaktionen mit einem bestimmten Datenabschnitt möglicherweise abgeschlossen hat. Je länger die Transaktion verlängert wird, desto länger wird die Sperre gehalten, sodass andere Threads nicht mit diesen Daten interagieren. Wie später gezeigt, umfasst dies auch verwandte Anpassungen, die innerhalb derselben Transaktion funktionieren und die Lebensdauer von Transaktionen wie synchronen Workflows erheblich verlängern können.
Im folgenden Beispiel wird die Schreibsperre für eine benutzerdefinierte Entität im Pre-Create Plug-in für ein Konto gesperrt, bis die gesamte mit der Erstellung des Kontos verbundene Logik abgeschlossen ist.
Intermittierende Fehler: Timing
Intermittierendes Verhalten ist ein offensichtliches Symptom der Blockierung von gleichzeitiger Aktivität. Wenn die Wiederholung genau der gleichen Aktion später erfolgreich ist, wenn sie zuvor fehlgeschlagen ist, besteht eine starke Wahrscheinlichkeit, dass der Fehler oder die Langsamkeit durch eine andere Aktion verursacht wurde, die gleichzeitig auftritt.
Das ist wichtig zu erkennen, da das Debuggen eines Problems häufig das Entfernen der beleidigenden Funktionalität auf das bloße Minimum erfordert. Wenn das Problem jedoch nur zeitweise auftritt, müssen Sie möglicherweise analysieren, wo die problematische Aktion mit einer anderen Aktivität im System kollidiert, und potenzielle Engpassstellen beachten. Sie können Konflikte vermeiden, indem Sie einen einzelnen Prozess optimieren; Je kürzer die Verarbeitungszeit ist, desto geringer ist jedoch die Wahrscheinlichkeit, dass die Aktivität mit anderen Prozessen in Konflikt ist.
Transaktionssteuerung
Während in den meisten Fällen die Art und Weise, wie Transaktionen verwendet werden, auf der Plattform verwaltet werden kann, gibt es Szenarien, in denen die erforderliche Logik komplex genug ist, um das Verständnis und den Einfluss auf Transaktionen zu erreichen, um die gewünschten Ergebnisse zu erzielen. Dataverse bietet viele verschiedene Anpassungsansätze, die sich auf die Art und Weise auswirken, wie Transaktionen verwendet werden.
Wenn Sie verstehen, wie jede Art von Anpassung an den Plattformtransaktionen teilnimmt, können Sie komplexe Szenarien effektiv in Dataverse modellieren und ihr Verhalten vorhersagen.
Wie bereits erwähnt, wird eine Transaktion nur während der Lebensdauer einer Anforderung an die Plattform gehalten, es ist nicht etwas, das beibehalten wird, sobald der Plattformschritt abgeschlossen ist. Diese begrenzte Dauer verhindert, dass Transaktionen von einem externen Client für lange Zeiträume gehalten und andere Plattformaktivitäten blockiert werden.
Die Aufgabe der Plattform besteht darin, die Konsistenz in der gesamten Plattformtransaktionspipeline aufrechtzuerhalten und gegebenenfalls Anpassungen zu ermöglichen, die an derselben Transaktion teilnehmen.
So verwenden modellgesteuerte Apps Transaktionen
Bevor Sie verstehen, wie Anpassungen mit der Plattform interagieren, ist es hilfreich, zu verstehen, wie modellgesteuerte Apps Anforderungen an die Plattform verwenden und wie sich dies auf die Transaktionsnutzung auswirkt.
| Operation | Description |
|---|---|
| Formulare (Abrufen) | • Geringe Auswirkungen auf andere Verwendungen. |
| Create | • Führt eine Erstellungsanforderung über die Plattform aus. • Geringe Auswirkungen auf andere Aktivitäten, da ein neuer Datensatz nichts anderes haben sollte, das blockiert. • Kann potenziell Sperrabfragen an die gesamte Tabelle blockieren, bis sie abgeschlossen ist. • Häufig können bei Anpassungen verwandte Aktionen ausgelöst werden, die Auswirkungen haben können. |
| Update | • Führt eine Aktualisierungsanforderung über die Plattform aus. • Wahrscheinlicher, dass Konflikte auftreten. Eine Updatesperre blockiert alle anderen Aktualisierungen dieses Datensatzes. • Löst oft andere Aktivitäten aus. • In einigen seltenen Fällen kann eine Updatesperre eine Lesesperre blockieren. Ein Beispiel dafür ist, dass Dataverse-Metadaten geändert werden: Lesevorgänge durch eine Dataverse-Metadatenänderungstransaktion werden durch Aktualisierungssperren blockiert. |
| Ansicht (RetrieveMultiple) | • Geringe Auswirkungen auf andere Verwendungen. • Schlecht funktionierende Abfragen können die Ressourcen der Datenbank belasten und Timeouts verursachen. |
Ereignispipeline: Plattformschritt
Wenn eine Ereignispipeline initiiert wird, wird eine SQL-Transaktion erstellt, um den Plattformschritt einzuschließen. Dadurch wird sichergestellt, dass alle datenbankaktivitäten, die von der Plattform ausgeführt werden, konsistent ausgeführt werden. Die Transaktion wird zu Beginn der Event-Pipeline angelegt und nach Abschluss der Verarbeitung entweder committed oder abgebrochen, je nachdem, ob sie erfolgreich war.
Anpassungsanforderungen
Es ist auch möglich, an einer von der Plattform initiierten Transaktion im Rahmen von Anpassungen teilzunehmen. Jede Art von Anpassung nimmt auf unterschiedliche Weise an Transaktionen teil. In den folgenden Abschnitten wird jeweils einer beschrieben.
- Synchronisieren von Plug-Ins (Vor- oder Nachbearbeitung: im Transaktionskontext)
- Synchronisieren von Plug-Ins (Vor- und Nachbearbeitung: im Transaktionskontext)
- Synchronisierungs-Plug-Ins (PreValidation: außerhalb des Transaktionskontexts)
- Synchronisierungs-Plug-Ins (PreValidation: im Transaktionskontext)
- Asynchrone Plugins
- Zusammenfassung der Verwendung von Plug-In-Transaktionen
- Synchrone Workflows
- Asynchrone Workflows
- Benutzerdefinierte Workflowaktivität
- Benutzerdefinierte Aktionen
- Webdienstanforderungen
Synchronisieren von Plug-Ins (Vor- oder Nachbearbeitung: im Transaktionskontext)
Wenn Plug-Ins für ein Ereignis registriert werden, können sie für eine PreOperation - oder PostOperation-Phase registriert werden, die sich innerhalb der Transaktion befindet. Alle Nachrichtenanforderungen des Plug-Ins werden innerhalb der Transaktion ausgeführt. Dies bedeutet, dass die Lebensdauer der Transaktion und alle gesperrten Sperren verlängert werden.
Synchronisieren von Plug-Ins (Vor- und Nachbearbeitung: im Transaktionskontext)
Plug-Ins können sowohl in der PreOperation- als auch in der PostOperation-Phase registriert werden. In diesem Fall kann die Transaktion noch weiter erweitert werden, da sie vom Anfang des PreOperation-Plug-Ins bis zum Abschluss des PostOperation-Plug-Ins erweitert wird.
Synchronisierungs-Plug-Ins (PreValidation: außerhalb des Transaktionskontexts)
Ein Plug-In kann auch registriert werden, um außerhalb der Plattformtransaktion zu handeln, indem es in der PreValidation-Phase registriert wird.
Hinweis
Sie erstellt KEINE eigene Transaktion. Daher wird jede Nachrichtenanforderung innerhalb des Plug-Ins unabhängig innerhalb der Datenbank bearbeitet.
Dieses Szenario gilt nur, wenn die PreValidation als erste Phase eines Pipelineereignisses aufgerufen wird. Obwohl das Plug-In in der PreValidation-Phase registriert ist, ist es möglich, dass es an einer Transaktion teilnimmt, wie im nächsten Abschnitt beschrieben. Es kann nicht angenommen werden, dass ein PreValidation-Plug-In nicht an einer Transaktion teilnimmt, obwohl es möglich ist, aus dem Ausführungskontext zu überprüfen, falls dies der Fall ist.
Synchronisierungs-Plug-Ins (PreValidation: im Transaktionskontext)
Das zugehörige Szenario tritt auf, wenn ein PreValidation-Plug-In registriert wird, aber das zugehörige Pipelineereignis von einer Nachrichtenanforderung innerhalb einer vorhandenen Transaktion ausgelöst wird.
Wie das folgende Diagramm zeigt, kann das Erstellen eines Kontos dazu führen, dass ein PreValidation-Plug-In anfangs außerhalb einer Transaktion ausgeführt wird, wenn die erste Erstellung ausgeführt wird. Wenn als Teil des Post-Plug-Ins eine Nachrichtenanforderung zum Erstellen eines zugehörigen untergeordneten Kontos gestellt wird, weil diese zweite Ereignis-Pipeline aus der übergeordneten Pipeline heraus initiiert wird, nimmt sie an derselben Transaktion teil.
In diesem Fall ermittelt das PreValidation-Plug-In , dass eine Transaktion bereits vorhanden ist, und nimmt daher an dieser Transaktion teil, obwohl es in der PreValidation-Phase registriert ist.
Wie bereits erwähnt, kann das Plug-In den Ausführungskontext für die IsInTransaction Eigenschaft überprüfen, was angibt, ob dieses Plug-In innerhalb einer Transaktion ausgeführt wird oder nicht.
Asynchrone Plugins
Ein Plug-In kann auch registriert werden, um asynchron zu agieren. In diesem Fall handelt das Plug-In auch außerhalb der Plattformtransaktion.
Hinweis
Das Plug-In erstellt keine eigene Transaktion. Jede Nachrichtenanforderung innerhalb des Plug-Ins wird unabhängig voneinander bearbeitet.
Zusammenfassung der Verwendung von Plug-In-Transaktionen
Zusammenfassung:
- Synchrone Plug-Ins nehmen in der Regel an Transaktionen teil.
- Asynchrone Plug-Ins nehmen niemals an einer Plattformtransaktion teil; jede Anforderung wird unabhängig ausgeführt.
- PreValidation-Plug-Ins erstellen keine Transaktion, nehmen aber teil, wenn bereits eine vorhanden ist.
| Event | Name der Phase | Transaktion ist noch nicht vorhanden | Transaktion ist bereits vorhanden |
|---|---|---|---|
| Vorabereignis | PreValidation | Es wird keine Transaktion erstellt. Nimmt nicht an der Transaktion teil; jede Anforderung verwendet eine unabhängige Transaktion für die Datenbank. | Beteiligt sich an einer vorhandenen Transaktion |
| Vorabereignis | PreOperation | Beteiligt sich an einer vorhandenen Transaktion | Beteiligt sich an einer vorhandenen Transaktion |
| Nachveranstaltung | PostOperation | Beteiligt sich an einer vorhandenen Transaktion | Beteiligt sich an einer vorhandenen Transaktion |
| Asynchron | N/A | Es wird keine Transaktion erstellt. Nimmt nicht an der Transaktion teil; jede Anforderung verwendet eine unabhängige Transaktion für die Datenbank. | N/A |
Synchrone Workflows
Aus der Sicht von Transaktionen fungieren synchrone Workflows als Plug-Ins für Vor- und Nachoperationen. Sie handeln daher innerhalb der Plattform-Pipeline-Transaktion und können denselben Einfluss auf die Dauer der Gesamtransaktion haben.
Asynchrone Arbeitsabläufe
Asynchrone Workflows werden außerhalb der Plattformtransaktion ausgelöst.
Hinweis
Der Workflow erstellt außerdem KEINE eigene Transaktion, und daher wird jede Nachrichtenanforderung innerhalb des Workflows unabhängig voneinander bearbeitet.
Das folgende Diagramm zeigt den asynchronen Workflow, der außerhalb der Plattformtransaktion fungiert, und jeder Schritt, der eine eigene unabhängige Transaktion initiiert.
Benutzerdefinierte Workflow-Aktivität
Benutzerdefinierte Workflowaktivitäten werden innerhalb des übergeordneten Workflowkontexts ausgeführt.
- Synchronisierungsworkflow: Handelt innerhalb der Transaktion
- Asynchroner Workflow: Handelt außerhalb der Transaktion
Das folgende Diagramm zeigt benutzerdefinierte Aktivitäten, die zuerst innerhalb eines synchronen Workflows und dann innerhalb eines asynchronen Workflows ausgeführt werden.
Benutzerdefinierte Aktionen
Benutzerdefinierte Aktionen können eigene Transaktionen erstellen. Dies ist ein wichtiges Feature. Eine benutzerdefinierte Aktion kann eine separate Transaktion außerhalb des Plattformschritts erstellen, je nachdem, ob sie für "Rollback aktivieren" konfiguriert ist.
- Rollbacksatz aktivieren
- Wenn die benutzerdefinierte Aktion durch eine Nachrichtenanforderung eines Plug-Ins aufgerufen wird, das in der Transaktion ausgeführt wird, und „Rollback aktivieren“ eingestellt ist, wirkt sie innerhalb der bestehenden Transaktion.
- Die benutzerdefinierte Aktion erstellt, falls nicht anders, eine neue Transaktion und wird innerhalb dieser ausgeführt.
- Rollback aktivieren nicht gesetzt
- Die benutzerdefinierte Aktion wirkt nicht innerhalb einer Transaktion.
Webservice-Anfragen
Wenn Anforderungen extern über Webdienste erfolgen, wird eine Pipeline erstellt und die Transaktionsverarbeitung innerhalb der Pipeline erfolgt wie zuvor beschrieben, eine Transaktion wird jedoch nicht verwaltet, sobald die Antwort zurückgegeben wird. Da der Zeitpunkt der nächsten Anfrage unbekannt ist, erlaubt die Plattform keine Sperrung von Ressourcen, die andere Aktivitäten blockieren würden.
Wenn mehrere Anforderungen innerhalb eines Plug-Ins mit demselben Ausführungskontext vorgenommen werden, ist es der allgemeine Ausführungskontext, der die Transaktionsreferenz verwaltet und in synchronen Plug-Ins sicherstellt, dass jede Anforderung innerhalb derselben Transaktion erfolgt. Die Möglichkeit, einen Ausführungskontext über Anforderungen hinweg aufrechtzuerhalten, ist außerhalb von Plug-Ins nicht verfügbar und daher kann eine Transaktion nicht über separate Anforderungen hinweg verwaltet werden, die extern vorgenommen wurden.
Es gibt zwei spezielle Nachrichten, in denen mehrere Aktionen als Teil einer einzelnen Webdienstanforderung an die Dataverse-Plattform übergeben werden können.
| Nachricht | Description |
|---|---|
ExecuteMultiple |
Dadurch können mehrere unabhängige Aktionen innerhalb derselben Webdienstanforderung übergeben werden. Jede dieser Anforderungen wird unabhängig von der Plattform ausgeführt, sodass kein Transaktionskontext zwischen Anforderungen besteht. |
ExecuteTransaction |
Dadurch können mehrere Aktionen innerhalb derselben Datenbanktransaktion verarbeitet werden, ähnlich wie mehrere Nachrichtenanforderungen innerhalb eines synchronen Plug-Ins. Diese Möglichkeit würde auch Auswirkungen auf mehrere Nachrichtenanforderungen haben; Das heißt, wenn jede Aktion sehr lange dauert (z. B. durch teure Abfragen oder Auslösen einer langen Kette verwandter synchroner Plug-Ins oder Workflows), kann dies zu Blockierungsproblemen in der breiteren Plattform führen. |
Web-API (OData)-Anforderungen in Plug-Ins
Verwenden Sie keine Web-API-(OData)-Anforderungen innerhalb eines Plug-Ins an dieselbe Organisation wie das Plug-In. Verwenden Sie immer die IOrganizationService Methoden. Dadurch kann der Transaktionskontext übergeben werden, damit der Vorgang an der Pipelinetransaktion teilnehmen kann.
Nächste Schritte
Zusätzlich zu Datenbanktransaktionen ist es wichtig, die Auswirkungen mehrerer gleichzeitiger Datenvorgänge auf das System zu schätzen. Weitere Informationen: Skalierbares Anpassungsdesign: Parallelitätsprobleme