Transactions can be nested one inside another. You might have an outer transaction to undo all the changes made by your routine and inner transactions to undo just portions of the changes made. When you work with nested transactions, you start with a top transaction which is also the outer most transaction.
事务可以由一个嵌套到另一个中。 外部的事务能够撤消你的程序所做的所有修改而内部事务仅仅能撤消部分修改。当你使用嵌套事务时,启动顶部事务也就等于启动外部事务。
As you start new transactions, they are added into the previous transaction. Nested transactions must be committed or aborted in the opposite order in which they are created. So if you have three transactions, you must close the third or innermost one before the second and finally the first. If you abort the first transaction, the changes made by all three transactions is undone.
当启动新事务时,它们也被添加进了前一个事务中。嵌套事务必须按与他们创建顺序相反的顺序提交或终止事务。因此,如果你有三个事务,在关闭第三个前就必须先关闭第三个或者说是最里面的一个,最后关闭第一个。如果终止了第一个事务,通过三个事务所做的修改都会撤消。
The following illustration shows how transactions appear when nested.
下面的插图显示在嵌套时事务如何出现。
The following example demonstrates using three transactions to create a Circle and Line object, and then change their colors. The color of the circle is changed in the second and third transaction, but since the third transaction is aborted only the changes made in the first and second transactions are saved to the database. Additionally, the number of active transactions is printed in the Command Line window as they are created and closed.
下面救命演示使用三个事务创建一个圆和直线对象,然后修改他们的颜色。圆的颜色将在第二个和第三个事务中修改,但是因为第三个事务被终止了,所以仅有第一个和第二个事务所做的修改被保存到数据库中。另外,当事务被创建和关闭时,活动事务的数量将会输出到命令行窗口中。
Imports Autodesk.AutoCAD.Runtime
Imports Autodesk.AutoCAD.ApplicationServices
Imports Autodesk.AutoCAD.DatabaseServices
Imports Autodesk.AutoCAD.Geometry
Imports Autodesk.AutoCAD.EditorInput
<CommandMethod("NestedTransactions")> _
Public Sub NestedTransactions()
'' 获得当前文档和数据库 Get the current document and database
Dim acDoc As Document = Application.DocumentManager.MdiActiveDocument
Dim acCurDb As Database = acDoc.Database
'' 创建对事务管理器的引用 Create a reference to the Transaction Manager
Dim acTransMgr As Autodesk.AutoCAD.DatabaseServices.TransactionManager
acTransMgr = acCurDb.TransactionManager
'' 创建一个新的事务 Create a new transaction
Using acTrans1 As Transaction = acTransMgr.StartTransaction()
'' 输出当前活动事务的数量 Print the current number of active transactions
acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _
acTransMgr.NumberOfActiveTransactions.ToString())
'' 以只读方式打开块表 Open the Block table for read
Dim acBlkTbl As BlockTable
acBlkTbl = acTrans1.GetObject(acCurDb.BlockTableId, OpenMode.ForRead)
'' 以写方式打开模型空间块表记录 Open the Block table record Model space for write
Dim acBlkTblRec As BlockTableRecord
acBlkTblRec = acTrans1.GetObject(acBlkTbl(BlockTableRecord.ModelSpace), _
OpenMode.ForWrite)
'' 创建一个半径为3圆心在5,5的圆 Create a circle with a radius of 3 at 5,5
Dim acCirc As Circle = New Circle()
acCirc.SetDatabaseDefaults()
acCirc.Center = New Point3d(5, 5, 0)
acCirc.Radius = 3
'' 添加新对象到模型空间和事务中 Add the new object to Model space and the transaction
acBlkTblRec.AppendEntity(acCirc)
acTrans1.AddNewlyCreatedDBObject(acCirc, True)
'' 创建第二个事务 Create the second transaction
Using acTrans2 As Transaction = acTransMgr.StartTransaction()
acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _
acTransMgr.NumberOfActiveTransactions.ToString())
'' 修改圆的颜色 Change the circle's color
acCirc.ColorIndex = 5
'' Get the object that was added to Transaction 1 and set it to the color 5
Dim acLine As Line = New Line(New Point3d(2, 5, 0), New Point3d(10, 7, 0))
acLine.SetDatabaseDefaults()
acLine.ColorIndex = 3
'' 添加新对象到模型空间和事务中 Add the new object to Model space and the transaction
acBlkTblRec.AppendEntity(acLine)
acTrans2.AddNewlyCreatedDBObject(acLine, True)
'' 创建第三个事务 Create the third transaction
Using acTrans3 As Transaction = acTransMgr.StartTransaction()
acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _
acTransMgr.NumberOfActiveTransactions.ToString())
'' 修改圆的颜色 Change the circle's color
acCirc.ColorIndex = 3
'' 更新图形的显示 Update the display of the drawing
acDoc.Editor.WriteMessage(vbLf)
acDoc.Editor.Regen()
'' 请求保留或放弃第三个事务所做修改 Request to keep or discard the changes in the third transaction
Dim pKeyOpts As PromptKeywordOptions = New PromptKeywordOptions("")
pKeyOpts.Message = vbLf & "Keep color change "
pKeyOpts.Keywords.Add("Yes")
pKeyOpts.Keywords.Add("No")
pKeyOpts.Keywords.Default = "No"
pKeyOpts.AllowNone = True
Dim pKeyRes As PromptResult = acDoc.Editor.GetKeywords(pKeyOpts)
If pKeyRes.StringResult = "No" Then
'' 放弃事务 3中所做修改 Discard the changes in transaction 3
acTrans3.Abort()
Else
'' 保存事务3中所做修改 Save the changes in transaction 3
acTrans3.Commit()
End If
'' 销毁事务 Dispose the transaction
End Using
acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _
acTransMgr.NumberOfActiveTransactions.ToString())
'' 保留事务 2所做修改 Keep the changes to transaction 2
acTrans2.Commit()
End Using
acDoc.Editor.WriteMessage(vbLf & "Number of transactions active: " & _
acTransMgr.NumberOfActiveTransactions.ToString())
'' 保留事务 1 所做修改 Keep the changes to transaction 1
acTrans1.Commit()
End Using
End Sub
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
[CommandMethod("NestedTransactions")]
public static void NestedTransactions()
{
// 获得当前文档和数据库 Get the current document and database
Document acDoc = Application.DocumentManager.MdiActiveDocument;
Database acCurDb = acDoc.Database;
// 创建对事务管理器的引用 Create a reference to the Transaction Manager
Autodesk.AutoCAD.DatabaseServices.TransactionManager acTransMgr;
acTransMgr = acCurDb.TransactionManager;
// 创建一个新的事务 Create a new transaction
using (Transaction acTrans1 = acTransMgr.StartTransaction())
{
// 输出当前活动事务的数量 Print the current number of active transactions
acDoc.Editor.WriteMessage("\nNumber of transactions active: " +
acTransMgr.NumberOfActiveTransactions.ToString());
// 以只读方式打开块表 Open the Block table for read
BlockTable acBlkTbl;
acBlkTbl = acTrans1.GetObject(acCurDb.BlockTableId,
OpenMode.ForRead) as BlockTable;
// 以写方式打开模型空间块表记录 Open the Block table record Model space for write
BlockTableRecord acBlkTblRec;
acBlkTblRec = acTrans1.GetObject(acBlkTbl[BlockTableRecord.ModelSpace],
OpenMode.ForWrite) as BlockTableRecord;
// 创建一个半径为3圆心在5,5的圆 Create a circle with a radius of 3 at 5,5
Circle acCirc = new Circle();
acCirc.SetDatabaseDefaults();
acCirc.Center = new Point3d(5, 5, 0);
acCirc.Radius = 3;
// 添加新对象到模型空间和事务中 Add the new object to Model space and the transaction
acBlkTblRec.AppendEntity(acCirc);
acTrans1.AddNewlyCreatedDBObject(acCirc, true);
// 创建第二个事务 Create the second transaction
using (Transaction acTrans2 = acTransMgr.StartTransaction())
{
acDoc.Editor.WriteMessage("\nNumber of transactions active: " +
acTransMgr.NumberOfActiveTransactions.ToString());
// 修改圆的颜色 Change the circle's color
acCirc.ColorIndex = 5;
// Get the object that was added to Transaction 1 and set it to the color 5
Line acLine = new Line(new Point3d(2, 5, 0), new Point3d(10, 7, 0));
acLine.SetDatabaseDefaults();
acLine.ColorIndex = 3;
// 添加新对象到模型空间和事务中 Add the new object to Model space and the transaction
acBlkTblRec.AppendEntity(acLine);
acTrans2.AddNewlyCreatedDBObject(acLine, true);
// 创建第三个事务 Create the third transaction
using (Transaction acTrans3 = acTransMgr.StartTransaction())
{
acDoc.Editor.WriteMessage("\nNumber of transactions active: " +
acTransMgr.NumberOfActiveTransactions.ToString());
// 修改圆的颜色 Change the circle's color
acCirc.ColorIndex = 3;
// 更新图形的显示 Update the display of the drawing
acDoc.Editor.WriteMessage("\n");
acDoc.Editor.Regen();
// 请求保留或放弃第三个事务所做修改 Request to keep or discard the changes in the third transaction
PromptKeywordOptions pKeyOpts = new PromptKeywordOptions("");
pKeyOpts.Message = "\nKeep color change ";
pKeyOpts.Keywords.Add("Yes");
pKeyOpts.Keywords.Add("No");
pKeyOpts.Keywords.Default = "No";
pKeyOpts.AllowNone = true;
PromptResult pKeyRes = acDoc.Editor.GetKeywords(pKeyOpts);
if (pKeyRes.StringResult == "No")
{
// 放弃事务 3中所做修改 Discard the changes in transaction 3
acTrans3.Abort();
}
else
{
// 保存事务3中所做修改 Save the changes in transaction 3
acTrans3.Commit();
}
// 销毁事务 Dispose the transaction
}
acDoc.Editor.WriteMessage("\nNumber of transactions active: " +
acTransMgr.NumberOfActiveTransactions.ToString());
// 保留事务 2所做修改 Keep the changes to transaction 2
acTrans2.Commit();
}
acDoc.Editor.WriteMessage("\nNumber of transactions active: " +
acTransMgr.NumberOfActiveTransactions.ToString());
// 保留事务 1 所做修改 Keep the changes to transaction 1
acTrans1.Commit();
}
}