• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Valued Mentor
    Posts: 321
    Registered: ‎05-06-2012

    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).

    Please use plain text.
    Distinguished Contributor
    Posts: 118
    Registered: ‎01-06-2003

    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  

    Please use plain text.
    Active Member
    Posts: 7
    Registered: ‎03-14-2012

    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

    Please use plain text.
    *Expert Elite*
    Posts: 1,640
    Registered: ‎04-29-2006

    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
    Please use plain text.
    Valued Mentor
    Posts: 321
    Registered: ‎05-06-2012

    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.

    Please use plain text.
    Distinguished Contributor
    Posts: 118
    Registered: ‎01-06-2003

    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 

    Please use plain text.