.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Document is Locked, but Write transactions do not happen?

11 REPLIES 11
SOLVED
Reply
Message 1 of 12
Millerni456
11105 Views, 11 Replies

Document is Locked, but Write transactions do not happen?

Hey all,

 

I open a document from a file (with read-only mode set to false).  Then I lock this document and start a transaction.

Within this transaction I delete all blocks that are named "MyBlockName", but none of them are deleted.

I also attempted editting attributes within a block, and the attribute textstring does not change one bit!

 

Anyways, after the transaction is committed, the database is saved, the lock is disposed, and the document is saved:

public void DoChanges(DrawingFile drawing)
        {   //DrawingFile.FullName is a valid string of a full file name. 
            AcAp.Document acadDoc = AcAp.Application.DocumentManager.Open(drawing.FullName,          false); 
            using (AcAp.DocumentLock docLock = acadDoc.LockDocument()) //Lock for modifying.
            {
                Database database = acadDoc.Database;
                using (Transaction trans = database.TransactionManager.StartTransaction())
                {
                    //GetBlockReferences returns a ObjectIdCollection containing all of the Id's of the 
//BlockReferences to with "MyBlockName" for its Name. foreach (ObjectId id in GetBlockReferences(database, "MyBlockName")) { trans.GetObject(id, OpenMode.ForWrite).Erase(); } }

//Save the database database.SaveAs(drawing.FullName, true, DwgVersion.Current, database.SecurityParameters);
}//Unlock the document
acadDoc.CloseAndSave(drawing.FullName); //Close/Save the document. }

 

So, what steps must I do in order to open a document from a file name, make changes to it, then save it?

 

The only thing that seems to not work here is making changes to it.

 

 

Thanks much,

-Nicholas

11 REPLIES 11
Message 2 of 12
Millerni456
in reply to: Millerni456

I should've tested that small bit I had up on the first post... it does what I need it to.

 

I've found two scenarios that cause the problem I am having and it has to do with "NESTING TRANSACTIONS AND LOCKING".

 

Take a look at these code samples,  the first one locks, then makes nested transactions..

using (AcAp.DocumentLock docLock = acadDoc.LockDocument()) //Lock for modifying.
            {
                using (Transaction tr = database.TransactionManager.StartTransaction())
                {
                    using (Transaction trans = database.TransactionManager.StartTransaction())
                    {
                        foreach (ObjectId id in GetBlockReferences(database, "MyBlockName"))
                        {
                            trans.GetObject(id, OpenMode.ForWrite).Erase();
                        }
                        trans.Commit();
                    }
                }
            }

 

Second, this sample starts the first transaction, then locks only for the nested transaction:

using (Transaction tr = database.TransactionManager.StartTransaction())
            {
                using (AcAp.DocumentLock docLock = acadDoc.LockDocument()) //Lock for modifying.
                {
                    using (Transaction trans = database.TransactionManager.StartTransaction())
                    {
                        foreach (ObjectId id in GetBlockReferences(database, "dai_title_e1"))
                        {
                            trans.GetObject(id, OpenMode.ForWrite).Erase();
                        }
                        trans.Commit();
                    }
                }
            }

 

So, I suppose that what I meant to ask was this:

How do I make changes to an AutoCAD document with nested transactions?

Tags (1)
Message 3 of 12
Jeff_M
in reply to: Millerni456

In your code, you never Commit() the transaction, so the changes made are not written to the database.

Jeff_M, also a frequent Swamper
EESignature
Message 4 of 12
Millerni456
in reply to: Jeff_M

Jeff_M,

I've ran tests before (and certainly on this program as well), and Commit() is called by default if the transaction is not aborted.

Calling Commit() manually produces the incorrect results still.

 

See my second post for more details as to why the changes do not persist.  I'm trying to make changes on a "Nested Transaction", and based on the way things are currently set up, I cannot save changes on nested transactons. 

 

 

 

I am not even sure it is POSSIBLE to make changes on nested transactions or if it is even ADVISED to do so.  I am fairly new with the Managed .NET API, so I still don't understand what is considered "Good" practice.

 

In the meantime, I am restructuring my program so that only 1 transaction exists.

 

PS:  The code I posted was only demo code.  It doesn't represent the core functionality of what I am doing.  I had a recursive function that opens AutoCAD drawings and makes transactions.  The recursive nature of this function created the nesting of transactions that I now am trying to avoid.

Message 5 of 12
jeff
in reply to: Millerni456


@Millerni456 wrote:
I've found two scenarios that cause the problem I am having and it has to do with "NESTING TRANSACTIONS AND LOCKING".

 

 

So, I suppose that what I meant to ask was this:

How do I make changes to an AutoCAD document with nested transactions?


First off locking only is only needed to make changes and and is done internaly unless from application context, so I do think that has anything to do with problem.

 

As Jeff just pointed out you missed committing transaction.

 

So if you understand for the changes to persist inside a transaction it must be commited.

 

That includes transactions so any changes made by a nested transaction would not persist if any of its outer transaction are not commited.

 

 

 

 

You can also find your answers @ TheSwamp
Message 6 of 12
jeff
in reply to: jeff

Using transaction

    ....

    ....

    ....

    10, 000 nested transaction and commited.

.......

end transaction ------ this outer transaction is not commited so any changes made it will not persist.

 

If you need more detail will post more but when a nested transaction is commited is passes the objects up to the containg transaction then that transaction

must be commited.

If a nested transaction is not commited then it will not pass the objects up to containg transaction to be changed.

 

You can also find your answers @ TheSwamp
Message 7 of 12
Millerni456
in reply to: jeff

Thanks jeff, and apologies Jeff_M,

 

I suppose that even if I "tested" it and "found out that Commit() is the default operation at the end of a transaction", that doesn't mean that I had a perfect test!

 

Many thanks to you both, I've second guessed my tests and found that they are false!

 

 

My new test was this, and as expected by jeff's post it actually works:

using (Transaction tr = database.TransactionManager.StartTransaction())
                {
                    using (Transaction trans = database.TransactionManager.StartTransaction())
                    {
                        foreach (ObjectId id in GetBlockReferences(database, "dai_title_e1"))
                        {
                            trans.GetObject(id, OpenMode.ForWrite).Erase();
                        }
                        trans.Commit();
                    }
                    tr.Commit();
                }

 

I wish I could actually test the committing of transactions on multiple levels with my REAL code, but my code has been changed.

 

So, I'd like to add that it is probably not a good idea to just simply Commit() every transaction.  A better idea would be to nest transactions properly, separating the Write transactions from Read transactions, and only commiting the Write transactions.  If the Commit() needs to be carried up to high level transactions, then that should be done.  This should improve performance while maintaining stable code.

 

 

Thanks again,

-Nicholas

Message 8 of 12
Jeff_M
in reply to: Millerni456

No problem Nicholas. We've all been there 'knowing' we checked everything and 'it should work how I have it', only to see the light after a 2x4 gets plopped upside our head. Smiley Happy Here's a quick read you might find interesting: http://adndevblog.typepad.com/autocad/2012/05/two-common-mistakes-with-transactions.html 

 

Also, as far as Commit() vs Abort(), I recall reading when I first got started, but cannot locate the source right now, that it is actually quicker, & better, to call Commit() except when you absolutely need to Abort(). I will try to find where I saw that and post back if I do.

Jeff_M, also a frequent Swamper
EESignature
Message 9 of 12
arcticad
in reply to: Jeff_M

http://usa.autodesk.com/adsk/servlet/index?siteID=123112&id=18216579

 

"If you’re just querying DBObjects in a Transaction and not modifying them, then it doesn’t matter if you commit the Transaction or not. Although committing a Transaction instead of aborting it is slightly faster if you’re opening lots (thousands) of objects in your Transaction"

---------------------------



(defun botsbuildbots() (botsbuildbots))
Message 10 of 12
Jeff_M
in reply to: arcticad

Thanks arcticad, I knew I had read it in my travels.

Jeff_M, also a frequent Swamper
EESignature
Message 11 of 12
jeff
in reply to: Jeff_M

Commitng is much faster with many object.

http://www.theswamp.org/index.php?topic=44037.msg493437#msg493437

You can also find your answers @ TheSwamp
Message 12 of 12
Millerni456
in reply to: Jeff_M

Okay, I understand now.  It must have something to do with Abort() doing a rollback.

 

Make that two 2x4's that hit me haha... I thought I read the opposite. But apparently I read exactly what you guys posted, but here instead:

http://through-the-interface.typepad.com/through_the_interface/2007/02/changing_the_co.html


// Not needed, but quicker than aborting
tr.Commit();


 

Funny how this keeps happening >_>..

 

Anyways... to modify my above statement.  ABORT only if REQUIRED, else COMMIT.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost