Author Topic: Exiting a using transation  (Read 4824 times)

0 Members and 1 Guest are viewing this topic.

Bryco

  • Water Moccasin
  • Posts: 1883
Exiting a using transation
« 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.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8787
  • AKA Daniel
Re: Exiting a using transation
« Reply #1 on: September 28, 2009, 08:14:29 PM »
No  :-)

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Exiting a using transation
« Reply #2 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.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8787
  • AKA Daniel
Re: Exiting a using transation
« Reply #3 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  :|

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Exiting a using transation
« Reply #4 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.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8787
  • AKA Daniel
Re: Exiting a using transation
« Reply #5 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))));

   }

Bobby C. Jones

  • Swamp Rat
  • Posts: 516
  • Cry havoc and let loose the dogs of war.
Bobby C. Jones

SomeCallMeDave

  • Guest
Re: Exiting a using transation
« Reply #7 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

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Exiting a using transation
« Reply #8 on: September 29, 2009, 11:24:21 AM »
Yes it could be snippet worthy.
Sorry Dave on Ruby.

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Exiting a using transation
« Reply #9 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.
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8787
  • AKA Daniel
Re: Exiting a using transation
« Reply #10 on: September 29, 2009, 06:08:09 PM »
Sorry, It happens  :lol:

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Exiting a using transation
« Reply #11 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();
It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8787
  • AKA Daniel
Re: Exiting a using transation
« Reply #12 on: September 29, 2009, 06:34:13 PM »
I meant ...Sorry, It happens ... "that I don't make sense"   :-)

sinc

  • Guest
Re: Exiting a using transation
« Reply #13 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.

mohnston

  • Bull Frog
  • Posts: 305
  • CAD Programmer
Re: Exiting a using transation
« Reply #14 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.

It's amazing what you can do when you don't know what you can't do.
CAD Programming Solutions