遇到一个口头机遇的答辩准备5(重新整理)
之前准备答辩的时候发现了不少问题,后来boss上的那位老师说我之前的答案没收到,要是觉得准备的不充分可以节后再补一份,于是正好重新整理下,再发一份(开心……)。这篇整理前面缺的信息……因为已经搞过一篇,节后的话还有几天时间,就想着结合之前的版本+答辩准备,手动整理一份哦……(啊……原来每个人题目不一样……我似乎做错题目了……老师还给了好多教材……节后……今天已经是放假结束了……刚交完之前的题目,发现邮件名字不一样……开始以为老师的名字,结果发现可能是做题者的名字……点开一看天塌了嘤嘤嘤)
一、嵌套事务(Nested Transactions)
AutoCAD .NET 支持在一个外层事务内部,再创建、使用内层事务。
但有2 条铁律,违反就会崩溃 / 报错:
- 内层事务必须在外层事务结束前提交 / 销毁
- 只有最外层事务能真正决定最终是否保存
- 内层事务提交 =临时生效
- 外层事务提交 =全部永久生效
- 外层事务回滚 =所有操作全部撤销(包括内层)
正确写法示例
// 最外层事务(主事务) using (Transaction trOuter = db.TransactionManager.StartTransaction()) { // 外层操作... // ====================== // 嵌套内层事务(完全合法) // ====================== using (Transaction trInner = db.TransactionManager.StartTransaction()) { // 内层图形操作 trInner.Commit(); // 内层必须提交/释放 } // 外层最后提交 → 所有操作才真正写入CAD trOuter.Commit(); }嵌套事务的真实机制
AutoCAD 的事务不是 “真的多层独立事务”,而是同一个事务的分层管理:
- 内层事务只是外层事务的子节点
- 内层
Commit()不会真正保存,只是把操作交给外层 - 只有最外层 Commit ()才会把所有修改真正写入图纸
- 只要外层回滚,内层所有操作都会全部作废
禁止的错误写法
// ❌ 错误:外层先提交,内层还在使用 trOuter.Commit(); using (Transaction trInner = ...) { }// ❌ 错误:内层没有 using / 没有正确释放 Transaction trInner = ...; trInner.Commit(); // 没 Dispose() 会导致句柄泄漏、CAD崩溃常见的使用场景
- 循环批量创建对象(每循环一个开一个小事务)
- 方法封装(A 方法开事务,调用 B 方法也开事务)
- 局部操作失败不影响整体(内层可以回滚,外层继续)
二、绘图次序 ≠ 图层顺序
图层顺序(Layer order)
只是图层管理器里的上下顺序对图形显示谁盖谁完全没用!
绘图次序(Draw Order)
才是真正控制 谁在上面、谁在下面 的显示顺序
- 后画的盖住先画的
- 用 DrawOrder 命令可以调整
- API 里用 DrawOrderTable 操作
绘图次序移动的是图元,不是图层
代码例子:
/// <summary> /// 将指定的实体放到【绘图最顶层】(盖住其他所有图形) /// 专门用于:让边界在种子上方 /// </summary> /// <param name="entityId">要置顶的实体ID(边界)</param> private void SetEntityToTop(ObjectId entityId) { // 拿到当前CAD文档的数据库 Database db = entityId.Database; // 必须用事务操作(CAD规范) using (Transaction tr = db.TransactionManager.StartTransaction()) { // 打开绘图次序表(控制谁盖谁的核心对象) DrawOrderTable drawOrder = tr.GetObject(db.DrawOrderTableId, OpenMode.ForWrite) as DrawOrderTable; // 获取模型空间/当前空间的ID ObjectId msId = db.CurrentSpaceId; // 把【目标实体】移到【所有图形的最顶端】 drawOrder.MoveToTop(msId, new ObjectIdCollection { entityId }); // 提交事务,保存修改 tr.Commit(); } }三、延时填充
……
四、命令间传参
可以写数据库里也可以写静态配置文件里
五、撤销组 API
db.TransactionManager.StartUndoGroup(); // 开始打包
db.TransactionManager.EndUndoGroup(); // 结束打包
六、析构函数(Destructor)
~ 类名 () = 这个对象被销毁、死亡、清理的时候自动调用的方法
作用:保证倒计时服务一定会被销毁,不会留在后台!
这个先不整了,先看题目哎,不知道节后几天……嘤嘤嘤
