Verwenden von Transaktionen zum Aktualisieren des Modells

Transaktionen stellen sicher, dass Änderungen, die am Store vorgenommen wurden, als Gruppe behandelt werden. Gruppierte Änderungen können als einzelne Einheit festgelegt oder rückgängig gemacht werden.

Wenn Ihr Programmcode im Visual Studio Visualization and Modeling SDK ein Element im Store ändert, hinzufügt oder löscht, muss dies stets innerhalb einer Transaktion erfolgen. Es muss eine aktive Instanz von Transaction bestehen, die dem Store zugeordnet ist, wenn die Änderung erfolgt. Dies gilt für alle Modellelemente, Beziehungen, Formen, Diagramme und deren Eigenschaften.

Der Transaktionsmechanismus hilft Ihnen, inkonsistente Zustände zu vermeiden. Wenn während einer Transaktion ein Fehler auftritt, werden alle Änderungen zurückgesetzt. Wenn Benutzer*innen einen Rückgängig-Befehl ausführen, wird jede zuletzt durchgeführte Transaktion als einzelner Schritt behandelt. Benutzer*innen können Teile einer kürzlich vorgenommenen Änderung nicht rückgängig machen, es sei denn, sie platzieren sie explizit in separate Transaktionen.

Beginnen einer Transaktion

Die bequemste Methode zum Verwalten einer Transaktion ist eine using-Anweisung, die in eine try...catch-Anweisung eingeschlossen ist:

Store store; ...
try
{
  using (Transaction transaction =
    store.TransactionManager.BeginTransaction("update model"))
    // Outermost transaction must always have a name.
  {
    // Make several changes in Store:
    Person p = new Person(store);
    p.FamilyTreeModel = familyTree;
    p.Name = "Edward VI";
    // end of changes to Store

    transaction.Commit(); // Don't forget this!
  } // transaction disposed here
}
catch (Exception ex)
{
  // If an exception occurs, the Store will be
  // rolled back to its previous state.
}

Wenn während der Änderungen eine Ausnahme auftritt, die das endgültige Commit() verhindert, wird der Store auf den vorherigen Zustand zurückgesetzt. Dadurch können Sie sicherstellen, dass Fehler das Modell nicht in einem inkonsistenten Zustand hinterlassen.

Sie können eine beliebige Anzahl von Änderungen innerhalb einer Transaktion vornehmen. Sie können neue Transaktionen innerhalb einer aktiven Transaktion öffnen. Die geschachtelten Transaktionen müssen einen Commit oder ein Rollback ausführen, bevor die enthaltende Transaktion endet. Weitere Informationen finden Sie im Beispiel zur TransactionDepth-Eigenschaft.

Um Ihre Änderungen dauerhaft zu machen, sollten Sie einen Commit der Transaktion ausführen, bevor sie verworfen wird. Wenn eine Ausnahme auftritt, die nicht innerhalb der Transaktion gefangen wird, wird der Store auf seinen Zustand vor den Änderungen zurückgesetzt.

Ausführen eines Rollbacks für eine Transaktion

Sie können eine der folgenden Taktiken verwenden, um sicherzustellen, dass der Store vor der Transaktion in seinem Zustand verbleibt oder wieder in seinen Zustand zurückgesetzt wird:

  1. Lösen Sie eine Ausnahme aus, die nicht innerhalb des Bereichs der Transaktion gefangen wird.

  2. Führen Sie explizit ein Rollback der Transaktion aus:

    this.Store.TransactionManager.CurrentTransaction.Rollback();
    

Transaktionen wirken sich nicht auf Objekte außerhalb des Store aus

Transaktionen steuern nur den Zustand des Store. Partielle Änderungen an externen Elementen wie Dateien, Datenbanken oder Objekten, die Sie mit normalen Typen außerhalb der DSL-Definition deklariert haben, können nicht rückgängig gemacht werden.

Wenn eine Ausnahme bei einer solche Änderung in einer Inkonsistenz mit dem Store resultieren kann, sollten Sie diese Möglichkeit im Ausnahmehandler behandeln. Um sicherzustellen, dass externe Ressourcen mit den Store-Objekten synchronisiert bleiben, können Sie jedes externe Objekt mithilfe von Ereignishandlern mit einem Element im Store koppeln. Weitere Informationen finden Sie unter Ereignishandler propagieren Änderungen außerhalb des Modells.

Regeln werden am Ende einer Transaktion ausgelöst

Am Ende einer Transaktion, bevor die Transaktion bereinigt wird, werden die Regeln ausgelöst, die an Elemente im Store angefügt sind. Jede Regel ist eine Methode, die auf ein geändertes Modellelement angewendet wird. Es gibt z. B. „Fix-up“-Regeln, die den Zustand einer Form aktualisieren, wenn sich das Modellelement geändert hat, und mit denen beim Erstellen eines Modellelements ein Shape erstellt wird. Es gibt keine festgelegte Auslösungsreihenfolge. Eine von einer Regel vorgenommene Änderung kann eine andere Regel auslösen.

Sie können eigene Regeln definieren. Weitere Informationen finden Sie unter Reagieren auf und Propagieren von Änderungen.

Regeln werden nach Befehlen zum Rückgängigmachen (Undo), Wiederholen (Redo) oder Rollback nicht ausgelöst.

Transaktionskontext

Jede Transaktion verfügt über ein Wörterbuch, in dem Sie alle gewünschten Informationen speichern können:

store.TransactionManager

.CurrentTransaction.TopLevelTransaction

.Context.Add(aKey, aValue);

Dies ist besonders nützlich für die Übertragung von Informationen zwischen Regeln.

Transaktionsstatus

In einigen Fällen müssen Sie vermeiden, dass eine Änderung propagiert wird, wenn die Änderung durch das Rückgängigmachen oder Wiederholen einer Transaktion verursacht wird. Dies kann beispielsweise passieren, wenn Sie einen Eigenschaftswerthandler schreiben, der einen anderen Wert im Store aktualisieren kann. Da beim Rückgängigmachen alle Werte im Store auf den vorherigen Status zurückgesetzt werden, ist es nicht erforderlich, aktualisierte Werte zu berechnen. Verwenden Sie diesen Code:

if (!this.Store.InUndoRedoOrRollback) {...}

Regeln können ausgelöst werden, wenn der Store zunächst aus einer Datei geladen wird. Durch folgenden Code vermeiden Sie, dass auf diese Änderungen reagiert wird:

if (!this.Store.InSerializationTransaction) {...}