トランザクションにより、ストアに対して行われた変更がグループとして扱われることが確認されます。 グループ化された変更は、1 つのユニットとしてコミットまたはロールバックできます。
プログラム コードが Visual Studio Visualization and Modeling SDK のストア内の要素を変更、追加、または削除するたびに、トランザクション内で行う必要があります。 変更が発生した場合、ストアに関連付けられている Transaction のアクティブなインスタンスが存在する必要があります。 これは、すべてのモデル要素、リレーションシップ、図形、ダイアグラム、およびそれらのプロパティに適用されます。
トランザクション メカニズムは、一貫性のない状態を回避するのに役立ちます。 トランザクション中にエラーが発生した場合、すべての変更がロールバックされます。 ユーザーが元に戻すコマンドを実行すると、最近の各トランザクションは 1 つのステップとして扱われます。 ユーザーは、明示的に別のトランザクションに配置しない限り、最近の変更の一部を元に戻すことはできません。
トランザクションを開く
トランザクションを管理する最も便利な方法は、using ステートメントで囲まれたtry...catch ステートメントを使用することです。
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.
}
変更中に最終的な Commit() を妨げる例外が発生した場合、ストアは以前の状態にリセットされます。 これにより、エラーによってモデルが不整合な状態にならないようにすることができます。
1 つのトランザクション内で任意の数の変更を行うことができます。 アクティブなトランザクション内で新しいトランザクションを開くことができます。 入れ子になったトランザクションは、含まれるトランザクションが終了する前にコミットまたはロールバックする必要があります。 詳細については、 TransactionDepth プロパティの例を参照してください。
変更を永続的にするには、トランザクションを破棄する前に Commit する必要があります。 トランザクション内でキャッチされない例外が発生した場合、ストアは変更前の状態にリセットされます。
トランザクションのロールバック
トランザクションの前にストアの状態を維持または元に戻すには、次のいずれかの方法を使用できます。
トランザクションのスコープ内でキャッチされない例外を発生させます。
トランザクションを明示的にロールバックします。
this.Store.TransactionManager.CurrentTransaction.Rollback();
トランザクションが非ストア オブジェクトに影響しない
トランザクションは、ストアの状態のみを管理します。 DSL 定義の外部にある通常の型で宣言したファイル、データベース、オブジェクトなどの外部項目に対して行われた部分的な変更を元に戻すことはできません。
例外によってこのような変更がストアと矛盾する可能性がある場合は、例外ハンドラーでその可能性に対処する必要があります。 外部リソースとストア オブジェクトの同期を維持する 1 つの方法は、イベント ハンドラーを使用して、各外部オブジェクトをストア内要素に結合することです。 詳細については、「 イベント ハンドラーによるモデルの外部への変更の反映」を参照してください。
トランザクションの終了時に適用されるルール
トランザクションの終了時に、トランザクションが破棄される前に、ストア内の要素にアタッチされたルールが実行されます。 各ルールは、変更されたモデル要素に適用されるメソッドです。 たとえば、モデル要素が変更されたときに Shape の状態を更新し、モデル要素の作成時に Shape を作成する "修正" ルールがあります。 指定された起動順序はありません。 別のルールを発動させる変更がルールによって行われ得ます。
独自のルールを定義できます。 ルールの詳細については、「 変更への応答と反映」を参照してください。
ルールは、元に戻すやり直しまたはロールバック コマンドの後には実行されません。
トランザクション コンテキスト
各トランザクションには、必要な情報を格納できるディクショナリがあります。
store.TransactionManager
.CurrentTransaction.TopLevelTransaction
.Context.Add(aKey, aValue);
これは、ルール間で情報を転送する場合に特に便利です。
トランザクションの状態
場合によっては、トランザクションの取り消しまたはやり直しによって変更が発生した場合は、変更の反映を回避する必要があります。 これは、たとえば、ストア内の別の値を更新できるプロパティ値ハンドラーを記述する場合に発生する可能性があります。 元に戻す操作では、ストア内のすべての値が以前の状態にリセットされるため、更新された値を計算する必要はありません。 次のコードを使用します。
if (!this.Store.InUndoRedoOrRollback) {...}
ルールは、ストアがファイルから初めて読み込まれるときに実行されることができます。 これらの変更に対応しないようにするには、次のコマンドを使用します。
if (!this.Store.InSerializationTransaction) {...}