You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
The Transaction class is the fundamental mechanism for safely accessing and modifying AutoCAD database objects. Transactions ensure data integrity by providing atomic operations - either all changes succeed or all are rolled back.
Key Concept: In AutoCAD .NET API, you must open database objects within a transaction to read or modify them. This prevents corruption and ensures thread safety.
Gets/sets whether transaction auto-deletes after commit/abort
TransactionManager
TransactionManager
Gets the transaction manager that created this transaction
Key Methods
Transaction Lifecycle
Method
Return Type
Description
Commit()
void
Commits all changes made during the transaction
Abort()
void
Rolls back all changes made during the transaction
Dispose()
void
Disposes the transaction (calls Abort if not committed)
Object Access
Method
Return Type
Description
GetObject(ObjectId, OpenMode)
DBObject
Opens a database object for reading or writing
GetObject(ObjectId, OpenMode, bool)
DBObject
Opens object with option to open erased objects
AddNewlyCreatedDBObject(DBObject, bool)
void
Adds a newly created object to the transaction
Common Usage Patterns
1. Basic Transaction Pattern
usingAutodesk.AutoCAD.ApplicationServices;usingAutodesk.AutoCAD.DatabaseServices;usingAutodesk.AutoCAD.Runtime;[CommandMethod("BASICTRANS")]publicvoidBasicTransactionExample(){Documentdoc=Application.DocumentManager.MdiActiveDocument;Databasedb=doc.Database;using(Transactiontr=db.TransactionManager.StartTransaction()){try{// Open model space for writingBlockTablebt=tr.GetObject(db.BlockTableId,OpenMode.ForRead)asBlockTable;BlockTableRecordbtr=tr.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite)asBlockTableRecord;// Create a circleCirclecircle=newCircle(newPoint3d(0,0,0),Vector3d.ZAxis,10.0);// Add to databasebtr.AppendEntity(circle);tr.AddNewlyCreatedDBObject(circle,true);// Commit changestr.Commit();}catch(System.Exceptionex){doc.Editor.WriteMessage($"\nError: {ex.Message}");// Transaction will auto-abort in Dispose if not committed}}}
2. Reading Object Properties
[CommandMethod("READLAYERS")]publicvoidReadLayersExample(){Documentdoc=Application.DocumentManager.MdiActiveDocument;Databasedb=doc.Database;Editored=doc.Editor;using(Transactiontr=db.TransactionManager.StartTransaction()){// Open layer table for readingLayerTablelt=tr.GetObject(db.LayerTableId,OpenMode.ForRead)asLayerTable;ed.WriteMessage("\n=== Layers in Drawing ===");foreach(ObjectIdlayerIdinlt){LayerTableRecordltr=tr.GetObject(layerId,OpenMode.ForRead)asLayerTableRecord;ed.WriteMessage($"\nLayer: {ltr.Name}, Color: {ltr.Color.ColorIndex}");}tr.Commit();// Good practice even for read-only operations}}
3. Modifying Existing Objects
[CommandMethod("MODIFYENTITY")]publicvoidModifyEntityExample(){Documentdoc=Application.DocumentManager.MdiActiveDocument;Databasedb=doc.Database;Editored=doc.Editor;// Prompt user to select an entityPromptEntityOptionspeo=newPromptEntityOptions("\nSelect a circle to modify: ");peo.SetRejectMessage("\nMust be a circle.");peo.AddAllowedClass(typeof(Circle),true);PromptEntityResultper=ed.GetEntity(peo);if(per.Status!=PromptStatus.OK)return;using(Transactiontr=db.TransactionManager.StartTransaction()){// Open circle for writingCirclecircle=tr.GetObject(per.ObjectId,OpenMode.ForWrite)asCircle;// Modify propertiescircle.Radius=circle.Radius*2.0;circle.ColorIndex=1;// Reded.WriteMessage($"\nCircle radius doubled to {circle.Radius}");tr.Commit();}}
4. Creating Multiple Objects
[CommandMethod("CREATEGRID")]publicvoidCreateGridExample(){Documentdoc=Application.DocumentManager.MdiActiveDocument;Databasedb=doc.Database;using(Transactiontr=db.TransactionManager.StartTransaction()){BlockTablebt=tr.GetObject(db.BlockTableId,OpenMode.ForRead)asBlockTable;BlockTableRecordbtr=tr.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite)asBlockTableRecord;// Create 5x5 grid of circlesfor(intx=0;x<5;x++){for(inty=0;y<5;y++){Circlecircle=newCircle(newPoint3d(x*20,y*20,0),Vector3d.ZAxis,5.0);btr.AppendEntity(circle);tr.AddNewlyCreatedDBObject(circle,true);}}tr.Commit();doc.Editor.WriteMessage("\nCreated 25 circles in grid pattern");}}
5. Nested Transactions (Advanced)
[CommandMethod("NESTEDTRANS")]publicvoidNestedTransactionExample(){Documentdoc=Application.DocumentManager.MdiActiveDocument;Databasedb=doc.Database;using(Transactiontr1=db.TransactionManager.StartTransaction()){BlockTablebt=tr1.GetObject(db.BlockTableId,OpenMode.ForRead)asBlockTable;BlockTableRecordbtr=tr1.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite)asBlockTableRecord;// Create first circleCirclecircle1=newCircle(newPoint3d(0,0,0),Vector3d.ZAxis,10.0);btr.AppendEntity(circle1);tr1.AddNewlyCreatedDBObject(circle1,true);// Nested transactionusing(Transactiontr2=db.TransactionManager.StartTransaction()){// Create second circleCirclecircle2=newCircle(newPoint3d(30,0,0),Vector3d.ZAxis,10.0);btr.AppendEntity(circle2);tr2.AddNewlyCreatedDBObject(circle2,true);tr2.Commit();// Nested commit}tr1.Commit();// Outer commit}}
6. Error Handling and Rollback
[CommandMethod("SAFETRANS")]publicvoidSafeTransactionExample(){Documentdoc=Application.DocumentManager.MdiActiveDocument;Databasedb=doc.Database;Editored=doc.Editor;using(Transactiontr=db.TransactionManager.StartTransaction()){try{BlockTablebt=tr.GetObject(db.BlockTableId,OpenMode.ForRead)asBlockTable;BlockTableRecordbtr=tr.GetObject(bt[BlockTableRecord.ModelSpace],OpenMode.ForWrite)asBlockTableRecord;// Simulate potential errorCirclecircle=newCircle(newPoint3d(0,0,0),Vector3d.ZAxis,-5.0);// Invalid radius!btr.AppendEntity(circle);tr.AddNewlyCreatedDBObject(circle,true);tr.Commit();}catch(Autodesk.AutoCAD.Runtime.ExceptionacEx){ed.WriteMessage($"\nAutoCAD Error: {acEx.Message}");// Transaction automatically aborts in Dispose}catch(System.Exceptionex){ed.WriteMessage($"\nGeneral Error: {ex.Message}");// Transaction automatically aborts in Dispose}}ed.WriteMessage("\nTransaction completed (changes rolled back if error occurred)");}
Best Practices
Always use using statement: Ensures transaction is disposed even if exceptions occur
Commit explicitly: Call Commit() when all operations succeed
Let Dispose handle abort: Don't call Abort() explicitly; Dispose() will abort if not committed
Open objects with minimum permissions: Use OpenMode.ForRead when possible
Minimize transaction scope: Keep transactions short to reduce locking
Handle exceptions: Wrap transaction code in try-catch blocks
Don't cross document boundaries: Each document has its own transaction manager