.NET

Reply
Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 11 of 17 (385 Views)

Re: Discussion Group ClassLibrary, please read!

12-02-2012 03:23 PM in reply to: Dale.Bartlett

dbartlett wrote:

 I generally pass the database, then start the transaction within the function. This is fundamental to building a reusable library so I would like to understand the best approach. Thanks, Dale.


Not really.

 

To make code reusable, you should avoid any creation or comitting of transactions from within APIs that you want to reuse.  The best approach is to write the API with the assumption that the caller has started and is managing the transaction. 

 

From within called APIs, you just get the TransactionManager from the Database you're working with and use it to open objects or add new objects to the drawing. 

 

I have a farily extensive library of reusable code and none of my methods start or commit transactions. That's always done at the outer-most level (for example, in a custom command, it would be done by the implementation of the command handler with the CommandMethod attribute).

Distinguished Contributor
Dale.Bartlett
Posts: 151
Registered: ‎01-06-2003
Message 12 of 17 (378 Views)

Re: Discussion Group ClassLibrary, please read!

12-02-2012 08:40 PM in reply to: DiningPhilosopher

I can understand the value of having the transactions outside of the library. What about passing document or database? The examples given with this post pass the document, then retrieve the database within the api. To use the library in a batch process, or possibly in a RealDWG application, wouldn't passing the database be a better option? Tony's comments here: http://forums.autodesk.com/t5/NET/WorkingDatabase-vs-MdiActiveDocument-Database/m-p/2455039/highligh... 

Thanks very much for the response. Dale  

Active Member
TobyRosenberg8728
Posts: 7
Registered: ‎03-14-2012
Message 13 of 17 (373 Views)

Re: Discussion Group ClassLibrary, please read!

12-02-2012 09:29 PM in reply to: DiningPhilosopher

Hi

I'm not quite sure about your approach for one simple reason: what happens if one method in one class calls another method in another class and both of them require a transaction being already started?

 

It is probably just me not really understanding the whole concept of when and where transactions should be started, so I would greatly appreciate if you could add some further explanations to your post.

Thanks

*Expert Elite*
_gile
Posts: 2,114
Registered: ‎04-29-2006
Message 14 of 17 (341 Views)

Re: Discussion Group ClassLibrary, please read!

12-03-2012 01:40 AM in reply to: TobyRosenberg8728

Hi,

 

I agree with DiningPhiliosopher and have too a quite large libraries of extension methods which have to be called from within a transaction.

 

If needed, the Database.TransactionManager or TopTransaction can be get from the Database passed as argument, but most of the time this argument too is not necessary and the Database can be get from any database resident DBObject or ObjectId passed to the method.

 

The method can handle the fact it is called from within a transaction or not throwing a Exception.

 

Adding some Xml comments may also help the user as they display with the intellisense.

 

Here's a little and simple example of an extension method to get a block reference 'effective name' which have to be called from within a transaction this way :

blockRef.GetEffectiveName()

 

        /// <summary>
        /// Gets the block effective name (have to be called from a transaction).
        /// </summary>
        /// <param name="br">The BlockReference instance the method applies to.</param>
        /// <returns>The block effective name.</returns>
        public static string GetEffectiveName(this BlockReference br)
        {
            if (br.IsDynamicBlock)
            {
                Database db = br.Database;
                if (db == null)
                {
                    throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NotInDatabase);
                }

                Transaction tr = db.TransactionManager.TopTransaction;
                if (tr == null)
                {
                    throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NotTopTransaction);
                }

                BlockTableRecord btr =
                    (BlockTableRecord)tr.GetObject(br.DynamicBlockTableRecord, OpenMode.ForRead);
                return btr.Name;
            }
            return br.Name;
        }

 

Gilles Chanteau
Valued Mentor
DiningPhilosopher
Posts: 370
Registered: ‎05-06-2012
Message 15 of 17 (297 Views)

Re: Discussion Group ClassLibrary, please read!

12-07-2012 05:29 AM in reply to: TobyRosenberg8728

TobyRosenberg8728 wrote:

Hi

I'm not quite sure about your approach for one simple reason: what happens if one method in one class calls another method in another class and both of them require a transaction being already started?

 

It is probably just me not really understanding the whole concept of when and where transactions should be started, so I would greatly appreciate if you could add some further explanations to your post.

Thanks


Whether methods are in the same or different classes has little to do with transactions. You place methods in classes based on more basic functional requirements, not on whether there is or isn't an active transaction.  I have methods that make calls to other methods, both in the same class as well as in other classes. All of them assume that there's an active transaction in cases where they access database objects.

 

The best place for managing transactions is at the outer-most or highest levels, because if the code fails, then any active transacation will be aborted and changes will be rolled back. If you instead start using nested transactions, then things become much more complicated much more quickly.  I rarely use nested transactions when I write code that modifies databases, as it's usually unnecessary.

Distinguished Contributor
Dale.Bartlett
Posts: 151
Registered: ‎01-06-2003
Message 16 of 17 (233 Views)

Re: Discussion Group ClassLibrary, please read!

01-12-2013 02:11 AM in reply to: DiningPhilosopher

Hi All, There wasn't a reply regarding whether to pass Document or Database:

What about passing document or database? The examples given with this post pass the document, then retrieve the database within the api. To use the library in a batch process, or possibly in a RealDWG application, wouldn't passing the database be a better option?

Can someone comment? I would like to proceed with developing a utility library, and this discussion has been very helpful. Thanks, Dale 

Distinguished Contributor
Dale.Bartlett
Posts: 151
Registered: ‎01-06-2003
Message 17 of 17 (126 Views)

Re: Discussion Group ClassLibrary, please read!

10-30-2013 01:21 AM in reply to: Dale.Bartlett
Hi All, I still haven't come to a conclusion re whether to pass Document or Database:
What about passing document or database? The examples given with this post pass the document, then retrieve the database within the api. To use the library in a batch process, or possibly in a RealDWG application, wouldn't passing the database be a better option?
Thanks, Dale
Post to the Community

Have questions about Autodesk products? Ask the community.

New Post
Announcements
Are You Going To Be @ AU 2014? Feel free to drop by our AU topic post and share your plans, plug a class that you're teaching, or simply check out who else from the community might be in attendance. Ohh and don't forgot to stop by the Autodesk Help | Learn | Collaborate booths in the Exhibit Hall and meet our community team if you get a chance!