对Revit事务机制的一些推测

news2025/2/24 0:35:07

什么是事务机制

首先,什么是事务机制。软件事务机制是指一种在软件系统中用于管理一系列操作的方法,这些操作要么全部成功完成,要么全部失败,不会出现部分完成的情况。事务机制确保了数据的一致性和完整性,特别是在并发操作和系统故障的情况下。以下是软件事务机制的一些关键特征:
原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不发生。如果事务中的任何一个操作失败,整个事务都会回滚到开始前的状态。
一致性(Consistency):事务必须使数据库从一个一致性状态转移到另一个一致性状态。在事务开始和结束时,数据库的数据完整性约束必须保持不变。
隔离性(Isolation):并发执行的事务彼此之间应该是隔离的,一个事务的执行不应该被其他事务干扰。这防止了事务之间的交互导致数据不一致。
持久性(Durability):一旦事务提交,它对系统的影响应该是永久性的。即使发生系统故障,事务的结果也应该被保留。

Revit 的事务 Transaction

从官方文档中可以看到 Revit 和事务相关的类为 Transaction,这个类的关键接口有 Start、Commit 和 Rollback。
在这里插入图片描述
在 Revit 中是需要显式得调用 Start,然后在操作完成后进行 Commit,或者操作失败后调用 Rollback。
官方例子:

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 = Plane.CreateByNormalAndOrigin(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 事务机制可能的实现

大型软件的实现肯定是非常复杂的,所以这里只是一个猜测。实际情况和下面的肯定存在巨大差异。
为了支持Undo和Redo功能,我们需要在Transaction类中添加一些额外的逻辑来记录操作的历史,并在需要时回滚或重做这些操作。以下是一个简化的C#实现,其中包含了基本的Undo和Redo功能:

using System;
using System.Collections.Generic;
public class Transaction
{
    private bool isStarted;
    private Stack<Action> undoStack;
    private Stack<Action> redoStack;
    public Transaction()
    {
        undoStack = new Stack<Action>();
        redoStack = new Stack<Action>();
    }
    public void Start(string transactionName)
    {
        if (isStarted)
            throw new InvalidOperationException("Transaction has already started.");
        isStarted = true;
        Console.WriteLine($"Transaction '{transactionName}' started.");
    }
    public void Commit()
    {
        if (!isStarted)
            throw new InvalidOperationException("No transaction has been started.");
        isStarted = false;
        redoStack.Clear(); // Clear the redo stack because a new commit creates a new point of no return
        Console.WriteLine("Transaction committed.");
    }
    public void Rollback()
    {
        if (!isStarted)
            throw new InvalidOperationException("No transaction has been started.");
        while (undoStack.Count > 0)
        {
            undoStack.Pop().Invoke(); // Execute all undo actions
        }
        isStarted = false;
        Console.WriteLine("Transaction rolled back.");
    }
    public void AddAction(Action action, Action undoAction)
    {
        if (!isStarted)
            throw new InvalidOperationException("No transaction has been started. Start a transaction before adding actions.");
        undoStack.Push(undoAction); // Push the undo action onto the stack
        action.Invoke(); // Execute the action
    }
    public void Undo()
    {
        if (undoStack.Count == 0)
            throw new InvalidOperationException("No actions to undo.");
        Action undoAction = undoStack.Pop();
        undoAction.Invoke(); // Execute the undo action
        redoStack.Push(() => undoAction); // Push the inverse action onto the redo stack
    }
    public void Redo()
    {
        if (redoStack.Count == 0)
            throw new InvalidOperationException("No actions to redo.");
        Action redoAction = redoStack.Pop();
        redoAction.Invoke(); // Execute the redo action
        undoStack.Push(() => redoAction); // Push the inverse action onto the undo stack
    }
}
// Example usage:
class Program
{
    static void Main(string[] args)
    {
        Transaction transaction = new Transaction();
        transaction.Start("Sample Transaction");
        // Add actions with corresponding undo actions
        transaction.AddAction(
            () => Console.WriteLine("Action 1 performed."),
            () => Console.WriteLine("Action 1 undone.")
        );
        transaction.AddAction(
            () => Console.WriteLine("Action 2 performed."),
            () => Console.WriteLine("Action 2 undone.")
        );
        // Commit the transaction
        transaction.Commit();
        // Undo the last action
        transaction.Undo();
        // Redo the last action
        transaction.Redo();
        // Rollback the transaction (undo all actions)
        transaction.Rollback();
    }

}
在这个例子中,Transaction类有两个栈:undoStack用于存储撤销操作,redoStack用于存储重做操作。每个操作都有一个对应的撤销操作,它们一起被添加到事务中。
AddAction方法用于添加操作和对应的撤销操作到事务中。Undo和Redo方法用于执行撤销和重做操作,并相应地更新栈。
在Main方法中,我们创建了一个Transaction实例,并添加了两个操作。然后我们提交事务,执行撤销和重做操作,并最后回滚事务。
请注意,这个示例是为了演示目的而简化的。在实际应用中,操作可能涉及更复杂的状态管理,并且需要处理并发和异常情况。此外,撤销和重做操作可能需要更精细的控制,例如操作特定的对象属性或恢复到特定的状态。

**注:**思想来源于博主,部分内容来自AI

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2304134.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《微软量子芯片:开启量子计算新纪元》:此文为AI自动生成

量子计算的神秘面纱 在科技飞速发展的今天,量子计算作为前沿领域,正逐渐走进大众的视野。它宛如一把神秘的钥匙,有望开启未来科技变革的大门,而微软量子芯片则是这把钥匙上一颗璀璨的明珠。 量子计算,简单来说,是一种遵循量子力学规律调控量子信息单元进行计算的新型计算…

SpringBoot+Vue+Mysql苍穹外卖

一.项目介绍 1.项目内容 苍穹外卖是一款为大学学子设计的校园外卖服务软件&#xff0c;旨在提供便捷的食堂外卖送至宿舍的服务。该软件包含系统管理后台和用户端&#xff08;微信小程序&#xff09;两部分&#xff0c;支持在线浏览菜品、添加购物车、下单等功能&#xff0c;并…

网络运维学习笔记 018 HCIA-Datacom综合实验02

文章目录 综合实验2sw3&#xff1a;sw4&#xff1a;gw&#xff1a;core1&#xff08;sw1&#xff09;&#xff1a;core2&#xff08;sw2&#xff09;&#xff1a;ISP 综合实验2 sw3&#xff1a; vlan 2 stp mode stp int e0/0/1 port link-type trunk port trunk allow-pass v…

QT 引入Quazip和Zlib源码工程到项目中,无需编译成库,跨平台,压缩进度

前言 最近在做项目时遇到一个需求&#xff0c;需要将升级的文件压缩成zip&#xff0c;再进行传输&#xff1b; 通过网络调研&#xff0c;有许多方式可以实现&#xff0c;例如QT私有模块的ZipReader、QZipWriter&#xff1b;或者第三方库zlib或者libzip或者quazip等&#xff1…

车载诊断架构 --- LIN节点路由转发注意事项

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

Eclipse2024中文汉化教程(图文版)

对应Eclipse,部分人需要中文汉化,本章教程,介绍如何对Eclipse进行汉化的具体步骤。 一、汉化前的Eclipse 默认安装Eclipse的时候,默认一般都是English的,我当前版本是使用的是2024-06版本的Eclipse。 二、汉化详细步骤 点击上方菜单选项卡,Hep——Install New Software……

医院安全(不良)事件上报系统源码,基于Laravel8开发,依托其优雅的语法与强大的扩展能力

医院安全&#xff08;不良&#xff09;事件上报系统源码 系统定义&#xff1a; 规范医院安全&#xff08;不良&#xff09;事件的主动报告&#xff0c;增强风险防范意识&#xff0c;及时发现医院不良事件和安全隐患&#xff0c;将获取的医院安全信息进行分析反馈&#xff0c;…

【第一节】C++设计模式(创建型模式)-工厂模式

目录 前言 一、面向对象的两类对象创建问题 二、解决问题 三、工厂模式代码示例 四、工厂模式的核心功能 五、工厂模式的应用场景 六、工厂模式的实现与结构 七、工厂模式的优缺点 八、工厂模式的扩展与优化 九、总结 前言 在面向对象系统设计中&#xff0c;开发者常…

爬虫小案例豆瓣电影top250(json格式)

1.json格式&#xff08;仅供学习参考&#xff09; import requests, json, jsonpathclass Start(object):# 类实例化时会执行def __init__(self):self.headers {user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.…

Spring事务原理 二

在上一篇博文《Spring事务原理 一》中&#xff0c;我们熟悉了Spring声明式事务的AOP原理&#xff0c;以及事务执行的大体流程。 本文中&#xff0c;介绍了Spring事务的核心组件、传播行为的源码实现。下一篇中&#xff0c;我们将结合案例&#xff0c;来讲解实战中有关事务的易…

SpringAI系列 - ToolCalling篇(二) - 如何设置应用侧工具参数ToolContext(有坑)

目录 一、引言二、集成ToolContext示例步骤1: 在`@Tool`标注的工具方法中集成`ToolConext`参数步骤2:`ChatClient`运行时动态设置`ToolContext`参数三、填坑一、引言 在使用AI大模型的工具调用机制时,工具参数都是由大模型解析用户输入上下文获取的,由大模型提供参数给本地…

本地部署MindSearch(开源 AI 搜索引擎框架),然后上传到 hugging face的Spaces——L2G6

部署MindSearch到 hugging face Spaces上——L2G6 任务1 在 官方的MindSearch页面 复制Spaces应用到自己的Spaces下&#xff0c;Space 名称中需要包含 MindSearch 关键词&#xff0c;请在必要的步骤以及成功的对话测试结果当中 实现过程如下&#xff1a; 2.1 MindSearch 简…

MyBatis Plus扩展功能

一、代码生成器 二、逻辑删除 三、枚举处理器 像状态字段我们一般会定义一个枚举&#xff0c;做业务判断的时候就可以直接基于枚举做比较。但是我们数据库采用的是int类型&#xff0c;对应的PO也是Integer。因此业务操作时必须手动把枚举与Integer转换&#xff0c;非常麻烦。 …

深度学习之自然语言处理CBOW预测及模型的保存

自然语言处理CBOW预测及模型的保存 目录 自然语言处理CBOW预测及模型的保存1 自然语言处理1.1 概念1.2 词向量1.2.1 one-hot编码1.2.2 词嵌入1.2.3 常见的词嵌入模型 2 CBOW预测模型搭建2.1 数据及模型确定2.1.1 数据2.1.2 CBOW模型2.1.3 词嵌入降维 2.2 数据预处理2.3 模型搭建…

qt项目配置部署

Test项目: 子项目testFileHelper 1.新建一个test项目的子项目:取名testFileHelper 2.编写测试用例 3.pro文件中引入qosbrowser 4.引入测试对象的cpp和头文件 2.在项目中引入资源文件testfile.txt,在其中输入abc 实现thrid目录复用 移动thrid 将thrild目录统一放在章…

java方法学习

java 方法 在Java中&#xff0c;方法是类&#xff08;或对象&#xff09;的行为或功能的实现。&#xff08;一起实现一个功能&#xff09;java的方法类似于其他语言的函数&#xff0c;是一段用来完成特定功能的代码片段。 方法是解决一类问题步骤的有序结合。 方法包含于类或…

基于vue和微信小程序的校园自助打印系统(springboot论文源码调试讲解)

第3章 系统设计 3.1系统功能结构设计 本系统的结构分为管理员和用户、店长。本系统的功能结构图如下图3.1所示&#xff1a; 图3.1系统功能结构图 3.2数据库设计 本系统为小程序类的预约平台&#xff0c;所以对信息的安全和稳定要求非常高。为了解决本问题&#xff0c;采用前端…

[漏洞篇]文件上传漏洞详解

[漏洞篇]文件上传漏洞详解 一、介绍 1. 概念 文件上传漏洞是指用户上传了一个可执行的脚本文件&#xff0c;并通过此脚本文件获得了执行服务器端命令的能力。这种攻击方式是最为直接和有效的&#xff0c;“文件上传” 本身没有问题&#xff0c;有问题的是文件上传后&#xf…

11.Docker 之分布式仓库 Harbor

Docker 之分布式仓库 Harbor Docker 之分布式仓库 Harbor1. Harbor 组成2. 安装 Harbor Docker 之分布式仓库 Harbor Harbor 是一个用于存储和分发 Docker 镜像的企业级 Registry 服务器&#xff0c;由 VMware 开源&#xff0c;其通过添加一些企业必需的功能特性&#xff0c;例…

Python项目源码34:网页内容提取工具1.0(Tkinter+requests+html2text)

------★Python练手项目源码★------- Python项目32&#xff1a;订单销售额管理系统1.0&#xff08;TkinterCSV&#xff09; Python项目31&#xff1a;初学者也能看懂的聊天机器人1.0源码&#xff08;命令行界面Re正则表达式&#xff09; Python项目源码30&#xff1a;待办事…