Transaction クラス

Transaction クラス

3 つのすべてのトランザクション オブジェクトは、いくつかのメソッドを共有します。

表 51: 一般的な Transaction オブジェクトのメソッド

メソッド

説明

Start

コンテキストを開始します

Commit

コンテキストを終了して、ドキュメントに対するすべての変更をコミットします

Rollback

コンテキストを終了して、ドキュメントに対するすべての変更を破棄します

GetStatus

Transaction オブジェクトの現在のステータスを返します

現在のステータスを返す GetStatus()メソッドに加えて、Commit および RollBack メソッドも、メソッドが正常に実行されたかどうかを示す TransactionStatus を返します。使用可能な TransactionStatus 値には、次が含まれます。

表 52: TransactionStatus 値

ステータス

説明

Uninitialized

オブジェクトがインスタンス化された後の初期値で、コンテキストはまだ開始されていません

Started

Transaction オブジェクトが正常に開始されました(Start が呼び出されました)

RolledBack

Transaction オブジェクトが正常にロールバックされました(Rollback が呼び出されました)

Committed

Transaction オブジェクトが正常にコミットされました(Commit が呼び出されました)

Pending

Transaction オブジェクトに対してサブミット、またはロールバックが試行されましたが、プロセスがまだ完了しておらず、(モードレス ダイアログで)エンドユーザの応答を待機しているというエラーが原因です。エラー処理が完了すると、ステータスが自動的に(Committed または RolledBack 状態に)更新されます。

トランザクション

トランザクションは、Revit モデルに変更を加えるために必要なコンテキストです。トランザクションは一度に 1 つだけ開くことができ、ネストは許可されません。各トランザクションには名前を付ける必要があり、これはトランザクションが正常にコミットされると、Revit の[元に戻す]メニューに表示されます。

コード領域 23-1: トランザクションを使用

public void CreatingSketch(UIApplication uiApplication)
{
    Autodesk.Revit.DB.Document document = uiApplication.ActiveUIDocument.Document;
    Autodesk.Revit.ApplicationServices.Application application = uiApplication.Application;

    // Create a few geometry lines. These lines are transaction (not in the model),
    // therefore they do not need to be created inside a document transaction.
    XYZ Point1 = XYZ.Zero;
    XYZ Point2 = new XYZ(10, 0, 0);
    XYZ Point3 = new XYZ(10, 10, 0);
    XYZ Point4 = new XYZ(0, 10, 0);

    Line geomLine1 = Line.CreateBound(Point1, Point2);
    Line geomLine2 = Line.CreateBound(Point4, Point3);
    Line geomLine3 = Line.CreateBound(Point1, Point4);

    // This geometry plane is also transaction and does not need a transaction
    XYZ origin = XYZ.Zero;
    XYZ normal = new XYZ(0, 0, 1);
    Plane geomPlane = application.Create.NewPlane(normal, origin);

    // In order to a sketch plane with model curves in it, we need
    // to start a transaction because such operations modify the model.

    // All and any transaction should be enclosed in a 'using'
    // block or guarded within a try-catch-finally blocks
    // to guarantee that a transaction does not out-live its scope.
    using (Transaction transaction = new Transaction(document))
    {
        if (transaction.Start("Create model curves") == TransactionStatus.Started)
        {
            // Create a sketch plane in current document
            SketchPlane sketch = SketchPlane.Create(document,geomPlane);

            // Create a ModelLine elements using the geometry lines and sketch plane
            ModelLine line1 = document.Create.NewModelCurve(geomLine1, sketch) as ModelLine;
            ModelLine line2 = document.Create.NewModelCurve(geomLine2, sketch) as ModelLine;
            ModelLine line3 = document.Create.NewModelCurve(geomLine3, sketch) as ModelLine;

            // Ask the end user whether the changes are to be committed or not
            TaskDialog taskDialog = new TaskDialog("Revit");
            taskDialog.MainContent = "Click either [OK] to Commit, or [Cancel] to Roll back the transaction.";
            TaskDialogCommonButtons buttons = TaskDialogCommonButtons.Ok | TaskDialogCommonButtons.Cancel;
            taskDialog.CommonButtons = buttons;

            if (TaskDialogResult.Ok == taskDialog.Show())
            {
                // For many various reasons, a transaction may not be committed
                // if the changes made during the transaction do not result a valid model.
                // If committing a transaction fails or is canceled by the end user,
                // the resulting status would be RolledBack instead of Committed.
                if (TransactionStatus.Committed != transaction.Commit())
                {
                    TaskDialog.Show("Failure", "Transaction could not be committed");
                }
            }
            else
            {
                transaction.RollBack();
            }
        }
    }
}

サブトランザクション

サブトランザクションを使用して、一連のモデル修正操作を閉じることができます。サブトランザクションはオプションです。モデルを修正するには、サブトランザクションは必要ありません。これらは、大きなタスクを論理的に小さなタスクに分割できるようにする便利なツールです。サブトランザクションは、既に開いているトランザクションでのみ作成でき、トランザクションを閉じる(コミットまたはロールバックされている)前に、サブトランザクションを閉じる(コミットまたはロールバックされている)必要があります。トランザクションと異なり、サブトランザクションはネストできますが、閉じているサブトランザクションを閉じる前に、ネストされたサブトランザクションを閉じる必要があります。サブトランザクションには名前がなく、Revit の[元に戻す]メニューには表示されません。

トランザクション グループ

TransactionGroup では、いくつかの個別のトランザクションを一緒にグループ化できます。これにより、グループの所有者が一度に多くのトランザクションを処理できます。トランザクション グループを閉じる場合は、ロールバックすることができます。これはグループに属する以前にコミットされたすべてのトランザクションがロールバックされるということです。ロールバックされない場合、グループをコミットまたは取り込むことができます。前者の場合、(グループの)すべてのコミットされたトランザクションがそのまま維持されます。後者の場合、グループのトランザクションは、グループ名を持つ 1 つのトランザクションに合成されます。

開いているトランザクションがない場合にのみ、トランザクション グループを開始でき、グルーブに含まれるすべてのトランザクションが閉じた(コミットまたはロールバックされた)後に、トランザクション グループを閉じる必要があります。トランザクション グループはネストできますが、ネストされたグループは、含んだグループを閉じる前に閉じる必要があります。トランザクション グループはオプションです。モデルに変更を加えるには、トランザクション グループは必要ありません。

次の例では、Assimilate()メソッドを使用して、TransactionGroup で 2 つの個別のトランザクションを合成する例を示します。次のコードは、[元に戻す]メニューに追加された、「Level and Grid」という名前の単一の[元に戻す]項目を作成します。

コード領域 23-2: 複数のトランザクションを TransactionGroup に組み合わせ

public void CompoundOperation(Autodesk.Revit.DB.Document document)
{
    // All and any transaction group should be enclosed in a 'using' block or guarded within
    // a try-catch-finally blocks to guarantee that the group does not out-live its scope.
    using (TransactionGroup transGroup = new TransactionGroup(document, "Level and Grid"))
    {
        if (transGroup.Start() == TransactionStatus.Started)
        {
            // We are going to call two methods, each having its own local transaction.
            // For our compound operation to be considered successful, both the individual
            // transactions must succeed. If either one fails, we will roll our group back,
            // regardless of what transactions might have already been committed.

            if (CreateLevel(document, 25.0) && CreateGrid(document, new XYZ(0,0,0), new XYZ(10,0,0)))
            {
                // The process of assimilating will merge the two (or any number of) committed
                // transaction together and will assign the grid's name to the one resulting transaction,
                // which will become the only item from this compound operation appearing in the undo menu.
                transGroup.Assimilate();
            }
            else
            {
                // Since we could not successfully finish at least one of the individual
                // operation, we are going to roll the entire group back, which will
                // undo any transaction already committed while this group was open.
                transGroup.RollBack();
            }
        }
    }
}

public bool CreateLevel(Autodesk.Revit.DB.Document document, double elevation)
{
    // All and any transaction should be enclosed in a 'using'
    // block or guarded within a try-catch-finally blocks
    // to guarantee that a transaction does not out-live its scope.
    using (Transaction transaction = new Transaction(document, "Creating Level"))
    {
        // Must start a transaction to be able to modify a document
               
        if( TransactionStatus.Started == transaction.Start())
        {
            if (null != document.Create.NewLevel(elevation))
            {
                // For many various reasons, a transaction may not be committed
                // if the changes made during the transaction do not result a valid model.
                // If committing a transaction fails or is canceled by the end user,
                // the resulting status would be RolledBack instead of Committed.
                return (TransactionStatus.Committed == transaction.Commit());
            }

            // For we were unable to create the level, we will roll the transaction back
            // (although on this simplified case we know there weren't any other changes)

            transaction.RollBack();
        }
    }
    return false;
}

public bool CreateGrid(Autodesk.Revit.DB.Document document, XYZ p1, XYZ p2)
{
    // All and any transaction should be enclosed in a 'using'
    // block or guarded within a try-catch-finally blocks
    // to guarantee that a transaction does not out-live its scope.
    using (Transaction transaction = new Transaction(document, "Creating Grid"))
    {
        // Must start a transaction to be able to modify a document
        if (TransactionStatus.Started == transaction.Start())
        {
            // We create a line and use it as an argument to create a grid
            Line gridLine = Line.CreateBound(p1, p2);
                 
            if ((null != gridLine) && (null != document.Create.NewGrid(gridLine)))
            {
                if (TransactionStatus.Committed == transaction.Commit())
                {
                return true;
                }
            }

            // For we were unable to create the grid, we will roll the transaction back
            // (although on this simplified case we know there weren't any other changes)

            transaction.RollBack();
        }
    }
    return false;
}