TheSwamp

Code Red => .NET => Topic started by: BillZndl on September 13, 2012, 11:42:28 AM

Title: Commit transaction necessary?
Post by: BillZndl on September 13, 2012, 11:42:28 AM
Win7 AutoCAD2012 VS2010:

I've searched for this quite a bit and cannot find a definite answer.

Do you always have to call trans.Commit(); on any transaction that you start?
Even if it's just to openMode.ForRead objects for informational purposes without changing anything in the database?
Example: I'm returning the ObjectId's for a calling method, do I need to call trans.Commit() before the using ends?.
Code: [Select]
private static ObjectId[] GetGroupObjectIDs()
        {
            Document document = AcadApp.DocumentManager.MdiActiveDocument;
            Editor editor = document.Editor;
            Database database = HostApplicationServices.WorkingDatabase;
           
            ObjectId[] EntIds = null;

            ObjectId oid = PickGroupInDrawing.SelectEntityOfGroup();

            if (!oid.IsNull)
            {
                using (document.LockDocument())
                {
                    using (Transaction trans = database.TransactionManager.StartTransaction())
                    {

                        ObjectId gid = GetGroupIdFromEnt(oid, trans);

                        if (!gid.IsNull)  //GroupId.
                        {
                            Group grp = trans.GetObject(gid, OpenMode.ForWrite, false) as Group;  //is group.

                            if (grp != null)
                            {
                                DBDictionary GrpDic = (DBDictionary)trans.GetObject(database.GroupDictionaryId, OpenMode.ForRead);

                                EntIds = grp.GetAllEntityIds();
                            }
                        }
                    }
                }
            }
            return EntIds;
        }

TIA
Title: Re: Commit transaction necessary?
Post by: TheMaster on September 13, 2012, 11:47:44 AM
Win7 AutoCAD2012 VS2010:

I've searched for this quite a bit and cannot find a definite answer.

Do you always have to call trans.Commit(); on any transaction that you start?
Even if it's just to openMode.ForRead objects for informational purposes without changing anything in the database?
Example: I'm returning the ObjectId's for a calling method, do I need to call trans.Commit() before the using ends?.
Code: [Select]
private static ObjectId[] GetGroupObjectIDs()
        {
            Document document = AcadApp.DocumentManager.MdiActiveDocument;
            Editor editor = document.Editor;
            Database database = HostApplicationServices.WorkingDatabase;
           
            ObjectId[] EntIds = null;

            ObjectId oid = PickGroupInDrawing.SelectEntityOfGroup();

            if (!oid.IsNull)
            {
                using (document.LockDocument())
                {
                    using (Transaction trans = database.TransactionManager.StartTransaction())
                    {

                        ObjectId gid = GetGroupIdFromEnt(oid, trans);

                        if (!gid.IsNull)  //GroupId.
                        {
                            Group grp = trans.GetObject(gid, OpenMode.ForWrite, false) as Group;  //is group.

                            if (grp != null)
                            {
                                DBDictionary GrpDic = (DBDictionary)trans.GetObject(database.GroupDictionaryId, OpenMode.ForRead);

                                EntIds = grp.GetAllEntityIds();
                            }
                        }
                    }
                }
            }
            return EntIds;
        }

TIA

According to Autodesk, there is some overhead associated with aborting a transaction. IF you don't call Commit(), the transaction is aborted when it's disposed.

If calling commit is somewhat bothersome, search the AutoCAD assemblies using Reflector or ILSpy, for a class called 'ReadOnlyTransaction'. This is essentially a specialization of Transaction that doesn't abort when its disposed (instead, it commits), and was intended for use when you're not modifying anything. 
Title: Re: Commit transaction necessary?
Post by: BillZndl on September 13, 2012, 12:22:45 PM
Not bothersome,
there's only a few places in my project where I start a transaction.

Didn't know if it might cause a mysterious crash of AutoCAD.

I'll look into you suggestions.

Thanks!




Title: Re: Commit transaction necessary?
Post by: Andrey Bushman on September 15, 2012, 01:07:04 PM
If calling commit is somewhat bothersome, search the AutoCAD assemblies using Reflector or ILSpy, for a class called 'ReadOnlyTransaction'. This is essentially a specialization of Transaction that doesn't abort when its disposed (instead, it commits), and was intended for use when you're not modifying anything.
Hi TT.
I can't find ReadOnlyTransaction type via ILSpy on AutoCAD 2013 SP 1.1. I have seen the AcDbMgd.dll, AcMgd.dll and AcCoreMgd.dll in "%ProgramFiles%\Autodesk\AutoCAD 2013" directory.
Title: Re: Commit transaction necessary?
Post by: BlackBox on September 15, 2012, 01:16:13 PM
I am not at my computer to look for myself (using IlSpy), but I am unable to find any documentation for ReadOnlyTransaction in a quick Google search (using my iPhone). Also surprised to find no mention of this from DevBlog (not really, but still).

Would you perhaps be able to provide us the name of the assembly in which this resides?

TIA