TheSwamp

Code Red => .NET => Topic started by: Bryco on September 28, 2009, 07:40:51 PM

Title: Exiting a using transation
Post by: Bryco on September 28, 2009, 07:40:51 PM
using (Transaction tr = db.TransactionManager.StartTransaction())
 {
      pline = tr.GetObject(plineId, OpenMode.ForWrite) as Polyline;
      if (!pline.Closed)
       {
             tr.Commit();
             MessageBox.Show("Please close the polyline: exiting");
             return;
         }
etc, etc

Do I really need the tr.commit above when exiting a transaction.
Title: Re: Exiting a using transation
Post by: It's Alive! on September 28, 2009, 08:14:29 PM
No  :-)
Title: Re: Exiting a using transation
Post by: Bryco on September 28, 2009, 08:16:37 PM
Thanks Daniel, saves a lot of extra writing.
I just couldn't figure out when it went out of scope.
Title: Re: Exiting a using transation
Post by: It's Alive! on September 28, 2009, 08:46:24 PM
Since "using" is just a "try catch finally" , the transaction is implicitly aborted when the transaction is disposed. I.e

Code: [Select]
  {
    Transaction tr = db.TransactionManager.StartTransaction();
    try
    {
      pline = tr.GetObject(plineId, OpenMode.ForWrite) as Polyline;
      if (!pline.Closed)
      {
        MessageBox.Show("Please close the polyline: exiting");
        return;
      }
    }
    finally
    {
     tr.Dispose(); //implicit abort
    }
   }

It was once mentioned that committing is faster than abort, I had ran a few tests a while back an couldn't tell the difference  :|
Title: Re: Exiting a using transation
Post by: Bryco on September 28, 2009, 09:54:43 PM
I don't know if this is an apples to apples test but is interesting.
Add a line in an empty dwg and chose it
Code: [Select]
        [CommandMethod("it")]
        public void testEscape()
        {
            Database db = HostApplicationServices.WorkingDatabase;
            Document doc = acadApp.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            PromptEntityResult per = ed.GetEntity("\nDon't pick a pline");
            if (per.Status != PromptStatus.OK) return;
            double start, now;

            start = Convert.ToDouble(DateTime.Now.Ticks);

            for(int i=0;i<1000;i++)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Polyline pline = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Polyline;
                    if (pline == null)
                    {
                        tr.Commit();
                        continue;
                    }
                    tr.Commit();
                }
            }
            now = Convert.ToDouble(DateTime.Now.Ticks);
            ed.WriteMessage("\nEllapsed time 1= 1" + ((now - start) / 10000.0).ToString());



            start = Convert.ToDouble(DateTime.Now.Ticks);
         
            for (int i = 0; i < 1000; i++)
            {
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                    Polyline pline = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Polyline;
                    if (pline == null) continue;
                    tr.Commit();
                }
            }
            now = Convert.ToDouble(DateTime.Now.Ticks);
            ed.WriteMessage("\nEllapsed time 2=" + ((now-start)/10000.0).ToString());



            start = Convert.ToDouble(DateTime.Now.Ticks);

            for (int i = 0; i < 1000; i++)
            {
                Transaction tr = db.TransactionManager.StartTransaction();
                try
                {
                    Polyline pline = tr.GetObject(per.ObjectId, OpenMode.ForRead) as Polyline;
                    if (pline == null)
                    {
                        continue;
                    }
                }
                finally
                {
                    tr.Dispose(); //implicit abort
                }
            }

            now = Convert.ToDouble(DateTime.Now.Ticks);
            ed.WriteMessage("\nEllapsed time 3=" + ((now - start) / 10000.0).ToString());

        }

Ellapsed time 1= 162.5024
Ellapsed time 2=953.1392
Ellapsed time 3=953.1392

I saw an older post commit vs abort I think where Tony was using objectid.open for readonly but I couldn't figure out how to put that in the same test.

Practically the time difference for one or 2 iterations would never be worth the typing.
Title: Re: Exiting a using transation
Post by: It's Alive! on September 29, 2009, 12:13:23 AM
This is a big difference!  :-o
If your using 09 or newer you can always do something like

Code: [Select]
{
    PromptEntityResult per =
     Application.DocumentManager.MdiActiveDocument.Editor.GetEntity("get it: ");

    Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage("{0}",
     per.ObjectId.ObjectClass.IsDerivedFrom(RXObject.GetClass(typeof(Polyline))));

   }
Title: Re: Exiting a using transation
Post by: Bobby C. Jones on September 29, 2009, 10:11:35 AM
You can have your cake and eat it to with a code snippet.

http://bobbycjones.spaces.live.com/blog/cns!2A36783BF92E8178!203.entry (http://bobbycjones.spaces.live.com/blog/cns!2A36783BF92E8178!203.entry)

http://bobbycjones.spaces.live.com/blog/cns!2A36783BF92E8178!206.entry (http://bobbycjones.spaces.live.com/blog/cns!2A36783BF92E8178!206.entry)
Title: Re: Exiting a using transation
Post by: SomeCallMeDave on September 29, 2009, 10:50:45 AM
Or you could use Ruby  and AcadHelper.rb  :)

Code: [Select]
  puts get_entity_id("\nGet it").ObjectClass.DxfName
Title: Re: Exiting a using transation
Post by: Bryco on September 29, 2009, 11:24:21 AM
Yes it could be snippet worthy.
Sorry Dave on Ruby.
Title: Re: Exiting a using transation
Post by: mohnston on September 29, 2009, 05:34:53 PM
Since "using" is just a "try catch finally" , the transaction is implicitly aborted when the transaction is disposed. I.e

Code: [Select]
  {
    Transaction tr = db.TransactionManager.StartTransaction();
    try
    {
      pline = tr.GetObject(plineId, OpenMode.ForWrite) as Polyline;
      if (!pline.Closed)
      {
        MessageBox.Show("Please close the polyline: exiting");
        return;
      }
    }
    finally
    {
     tr.Dispose(); //implicit abort
    }
   }

It was once mentioned that committing is faster than abort, I had ran a few tests a while back an couldn't tell the difference  :|

So, does an Abort automatically Commit?
That doesn't make sense.
Title: Re: Exiting a using transation
Post by: It's Alive! on September 29, 2009, 06:08:09 PM
Sorry, It happens  :lol:
Title: Re: Exiting a using transation
Post by: mohnston on September 29, 2009, 06:29:02 PM
This from help does not agree:
Quote
When using transactions, you are able to decide when changes to objects are saved to the drawing database. You use the Commit method to save the changes made to the objects opened within a transaction. If your program encounters an error you can rollback any changes made within a transaction with the Abort method.
If Commit is not called before Dispose is called, all changes made within the transaction are rolled back. Whether Commit or Abort are called, you need to call Dispose to signal the end of the transaction. If the transaction object is started with the Using statement, you do not have to call Dispose.
VB.NET

'' Commit the changes made within the transaction
<transaction>.Commit()
 
'' Abort the transaction and rollback to the previous state
<transaction>.Abort()
C#

// Commit the changes made within the transaction
<transaction>.Commit();
 
// Abort the transaction and rollback to the previous state
<transaction>.Abort();
Title: Re: Exiting a using transation
Post by: It's Alive! on September 29, 2009, 06:34:13 PM
I meant ...Sorry, It happens ... "that I don't make sense"   :-)
Title: Re: Exiting a using transation
Post by: sinc on September 29, 2009, 07:07:06 PM
I think Daniel meant this:

Code: [Select]
 {
    Transaction tr = db.TransactionManager.StartTransaction();
    try
    {
      pline = tr.GetObject(plineId, OpenMode.ForWrite) as Polyline;
      if (!pline.Closed)
      {
        MessageBox.Show("Please close the polyline: exiting");
        return;
      }
      // do some other stuff, perhaps changing the pline
      tr.Commit();
    }
    finally
    {
     tr.Dispose(); //implicit abort if transaction has not been committed
    }
   }

Commits never happen implicitly; without the commit, nothing will be written to the database.

Of course, the usual process is to use "using" constructs instead, since it's cleaner.

It was once mentioned that committing is faster than abort, I had ran a few tests a while back an couldn't tell the difference  :|

I've seen Kean say that multiple times in his blog, but I haven't actually tested it myself.
Title: Re: Exiting a using transation
Post by: mohnston on September 29, 2009, 07:27:29 PM
using (Transaction tr = db.TransactionManager.StartTransaction())
 {
      pline = tr.GetObject(plineId, OpenMode.ForWrite) as Polyline;
      if (!pline.Closed)
       {
             tr.Commit();
             MessageBox.Show("Please close the polyline: exiting");
             return;
         }
etc, etc

Do I really need the tr.commit above when exiting a transaction.
So Daniel's answer (No) is correct only if you do not want to save any changes to the database.
If you are just looking then no need to commit.

Title: Re: Exiting a using transation
Post by: sinc on September 29, 2009, 09:20:09 PM
Well, then you get into this, that Bryco posted:

Quote
Ellapsed time 1= 162.5024
Ellapsed time 2=953.1392
Ellapsed time 3=953.1392

In his code, (1) commits the transaction.  Meanwhile,  assuming you follow his directions and pick a line (or anything except a polyline) in the drawing, (2) and (3) are equivalent, and abort the transactions.  (2) and (3) take more than 5 times as long as (1).

But of course, if you are not creating a lot of transactions, you may not really care much about the difference in time between Abort and Commit.  However, for some purposes, the difference might be significant.  For example, if you write a command that might be called a lot by a script, then you may want to choose the one that runs fastest.  So this all seems to indicate that you may want to do like Kean recommends, and use Commit, unless you really want to Abort and roll back any changes.
Title: Re: Exiting a using transation
Post by: Kerry on September 29, 2009, 10:14:30 PM
I was corrected here :)

http://www.theswamp.org/index.php?topic=29379.msg349347#msg349347