We discussed about the Database TransactionManager and Document TransactionManager before. We also did a small experiment and reached the conclusion that the two TransactionManager instances are likely the same thing for the current database, which is opened and visible in the AutoCAD drawing editor.
What about for external databases then (created by the new Database() call and loaded by the ReadDwgFile() method)?
Let’s figure it out in this post. The following VB.NET code serves for this purpose.
<CommandMethod("DocTransManagerNoWhere")> _
Public Shared Sub DocTransManagerNoWhere_Method()
Dim ed As Editor = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor
Dim doc As Document = MgdAcApplication.DocumentManager.MdiActiveDocument
Dim db As Database = HostApplicationServices.WorkingDatabase
Try
Using extDb As New Database(False, True)
extDb.ReadDwgFile("c:\temp\test1.dwg", FileShare.ReadWrite, False, "")
Using dbTr As Transaction = extDb.TransactionManager.StartTransaction()
Dim btr As BlockTableRecord = DirectCast(dbTr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(extDb), OpenMode.ForRead), BlockTableRecord)
Dim count As Integer = 0
For Each id As ObjectId In btr
Dim ent As Entity = TryCast(dbTr.GetObject(id, OpenMode.ForWrite), Entity)
ent.ColorIndex = 1
count += 1
Next
ed.WriteMessage(String.Format(vbLf & "{0} have been changed in the transaction started by the External Database TransactionManager.", count))
dbTr.Commit()
End Using
extDb.SaveAs(extDb.Filename, DwgVersion.Current)
End Using
Catch ex As System.Exception
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(Environment.NewLine + ex.Message)
End Try
Try
Using extDb As New Database(False, True)
extDb.ReadDwgFile("c:\temp\test1.dwg", FileShare.ReadWrite, False, "")
Using dbTr As Transaction = db.TransactionManager.StartTransaction()
Dim btr As BlockTableRecord = DirectCast(dbTr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(extDb), OpenMode.ForRead), BlockTableRecord)
Dim count As Integer = 0
For Each id As ObjectId In btr
Dim ent As Entity = TryCast(dbTr.GetObject(id, OpenMode.ForWrite), Entity)
ent.ColorIndex = 2
count += 1
Next
ed.WriteMessage(String.Format(vbLf & "{0} have been changed in the transaction started by the Working Database TransactionManager.", count))
dbTr.Commit()
End Using
extDb.SaveAs(extDb.Filename, DwgVersion.Current)
End Using
Catch ex As System.Exception
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(Environment.NewLine + ex.Message)
End Try
Try
Using extDb As New Database(False, True)
extDb.ReadDwgFile("c:\temp\test1.dwg", FileShare.ReadWrite, False, "")
Using docTr As Transaction = doc.TransactionManager.StartTransaction()
Dim btr As BlockTableRecord = DirectCast(docTr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(extDb), OpenMode.ForRead), BlockTableRecord)
Dim count As Integer = 0
For Each id As ObjectId In btr
Dim ent As Entity = TryCast(docTr.GetObject(id, OpenMode.ForWrite), Entity)
ent.ColorIndex = 3
count += 1
Next
ed.WriteMessage(String.Format(vbLf & "{0} have been changed in the transaction started by the Document TransactionManager.", count))
docTr.Commit()
End Using
extDb.SaveAs(extDb.Filename, DwgVersion.Current)
End Using
Catch ex As System.Exception
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(Environment.NewLine + ex.Message)
End Try
End Sub
Here is the output:
Command: DocTransManagerNoWhere
5 have been changed in the transaction started by the External Database TransactionManager.
eNotFromThisDocument
eNotFromThisDocument
Therefore, the TransactionManager of the external Database is still good, however, Document TransactionManager is found nowhere for the external Database since it does not have Document associated with.
Since the Document TransactionManager does not seem to bring any extra benefits than the Database TransactionManager even for the working database, why should we bother to use two different approaches to start transactions? Sticking to the Database TransactionManager is a good practice then. Firstly, the same code will apply to both the working database and external databases. Secondly, it will be easier to port code from one place to another.
The leading edge AutoCAD .NET Addin Wizard (AcadNetAddinWizard) provides various project wizards, item wizards, coders and widgets to help program AutoCAD .NET addins.
Out of curiosity have you tested aborting transactions on side database with Database constructor nodocument set to True as in this example?
Was wondering if performance hits from aborting transaction were from an abort doing graphic flush for each object in undo file, and thought maybe you would not have same performance issue with examples above since a document is required for using the UNDO mechanism.
Posted by: JeffH | 02/25/2015 at 04:36 PM
Jeff, a good point. We will address it in a post when getting a chance.
Posted by: Spiderinnet1 | 03/02/2015 at 09:44 PM
Hi Jeff again. It's proved the fact is the same for external databases. Committing transactions performs better than aborting. The latest post has details and code snippets.
Posted by: Spiderinnet1 | 03/05/2015 at 09:31 PM
Thanks!
Posted by: JeffH | 03/06/2015 at 08:21 PM