We discussed about the Database TransactionManager and Document TransactionManager a while back. 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 those external databases (created by the new Database() call and loaded by the ReadDwgFile method) then?
Let’s figure it out in this post. The following code and command serves for this purpose.
[CommandMethod("DocTransManagerNoWhere")]
public static void DocTransManagerNoWhere_Method()
{
Editor ed = MgdAcApplication.DocumentManager.MdiActiveDocument.Editor;
Document doc = MgdAcApplication.DocumentManager.MdiActiveDocument;
Database db = HostApplicationServices.WorkingDatabase;
try
{
using (Database extDb = new Database(false, true))
{
extDb.ReadDwgFile("c:\\temp\\test1.dwg", FileShare.ReadWrite, false, "");
using (Transaction dbTr = extDb.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)dbTr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(extDb), OpenMode.ForRead);
int count = 0;
foreach (ObjectId id in btr)
{
Entity ent = dbTr.GetObject(id, OpenMode.ForWrite) as Entity;
ent.ColorIndex = 1;
count++;
}
ed.WriteMessage(string.Format("\n{0} have been changed in the transaction started by the External Database TransactionManager.", count));
dbTr.Commit();
}
extDb.SaveAs(extDb.Filename, DwgVersion.Current);
}
}
catch (System.Exception ex)
{
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(Environment.NewLine + ex.Message);
}
try
{
using (Database extDb = new Database(false, true))
{
extDb.ReadDwgFile("c:\\temp\\test1.dwg", FileShare.ReadWrite, false, "");
using (Transaction dbTr = db.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)dbTr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(extDb), OpenMode.ForRead);
int count = 0;
foreach (ObjectId id in btr)
{
Entity ent = dbTr.GetObject(id, OpenMode.ForWrite) as Entity;
ent.ColorIndex = 2;
count++;
}
ed.WriteMessage(string.Format("\n{0} have been changed in the transaction started by the Working Database TransactionManager.", count));
dbTr.Commit();
}
extDb.SaveAs(extDb.Filename, DwgVersion.Current);
}
}
catch (System.Exception ex)
{
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(Environment.NewLine + ex.Message);
}
try
{
using (Database extDb = new Database(false, true))
{
extDb.ReadDwgFile("c:\\temp\\test1.dwg", FileShare.ReadWrite, false, "");
using (Transaction docTr = doc.TransactionManager.StartTransaction())
{
BlockTableRecord btr = (BlockTableRecord)docTr.GetObject(SymbolUtilityServices.GetBlockModelSpaceId(extDb), OpenMode.ForRead);
int count = 0;
foreach (ObjectId id in btr)
{
Entity ent = docTr.GetObject(id, OpenMode.ForWrite) as Entity;
ent.ColorIndex = 3;
count++;
}
ed.WriteMessage(string.Format("\n{0} have been changed in the transaction started by the Document TransactionManager.", count));
docTr.Commit();
}
extDb.SaveAs(extDb.Filename, DwgVersion.Current);
}
}
catch (System.Exception ex)
{
MgdAcApplication.DocumentManager.MdiActiveDocument.Editor.WriteMessage(Environment.NewLine + ex.Message);
}
}
Here is the output:
Command: DocTransManagerNoWhere
5 have been changed in the transaction started by the External Database
TransactionManager.
eNotFromThisDocument
eNotFromThisDocument
So the TransactionManager of the external Database is still good, but the thing is different from the working database here since the Document of the external Database can be found nowhere along with the Document TransactionManager.
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 then? Sticking to the Database TransactionManager is surely 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.
Hey Siperinnet1,
Just looked at it quickly in reflector and looks like the Document TransactionManager just inherits the Database TransactionManager and just adds the functionality to flush graphics.
Also use a Apptranction that overrides Commit that just calls FlushGraphics after using Transaction functionality.
http://forums.autodesk.com/t5/NET/doc-TransactionManager-or-db-TransactionManager/m-p/3763848/highlight/false#M33215
Posted by: JeffH | 01/29/2013 at 06:19 AM
JeffH, thanks for the good additions.
It makes sense since those side databases generally don't have documents associated with and/or don't have to worry about graphics flushes.
Posted by: Spiderinnet1 | 01/29/2013 at 05:19 PM