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

Transaction Best Practices

3 REPLIES 3
SOLVED
Reply
Message 1 of 4
nshupeFMPE3
447 Views, 3 Replies

Transaction Best Practices

I noticed this thread when I came to post this. This thread had some really interesting talk around Transaction, so it was very serendipitous. 

So it seems I'm not the only one wondering when it comes to Transactions; What are the best practices for using Transactions? 

I've been running into problems recently as my plugin gets more complicated about having things already be open in either another transaction. Or having an object get opened and then closed in a transaction, and then needing to open it again and receiving an error. 

Which lead me to once again start looking online for people's thoughts and opinions and the documentation around Transactions.

So far I see that most people agree if your doing some sort of Read operations, to use a StartOpenCloseTransaction. 
I've also read that StartOpenCloseTransaction does not nest the same way StartTransaction does. 

I use StartOpenCloseTransaction almost exclusively throught my code, for reading and writing. And I have a lot of helper functions that can optionally take a transaction, and if not given one will open their own StartOpenCloseTransaction. But I think that might be where I'm beginning to run into problems.

So the question is, what are the best practices for using Transactions?

Labels (4)
3 REPLIES 3
Message 2 of 4

If you write a lot of helper functions or classes that you want to be reusable, then the best way to do it is to not start and end transactions within those helper functions, but rather have them take a transaction as an argument. This is useful because it allows you to pass the function either of the two basic types of transactions, allowing the function to be usable in a variety of different contexts, such as Within a command or within an event handler.

 

Since the usage context is what often dictates what type of transaction you may have to use, its helpful to avoid coupling your reusable code to the TopTransaction, or to either of the two types of transactions.

 

Another good practice is to start and end a transaction at the same level within your code. For example, there was recently some code posted here in which a transaction was started by a calling method and was ended by a method that it called, which is not a pattern that I would recommend.

 

Another good practice is to avoid aborting a transaction if there were no changes to the database during the transaction's life. Aborting a transaction has significant overhead that is not encountered by committing the transaction.

 

Try to avoid user interaction while a transaction is active, especially if it is the kind returned by StartTransaction(). If the user were to change settings or Pan/Zoom the display while a transaction is active and it is subsequently aborted, that will also undo the user's changes (including pans/zooms) to the editor as well. That's another good reason to avoid aborting a transaction as well.

 

One of the things that is not well understood about transactions, is nesting. In fact, there is no such thing as a 'nested transaction' . The only thing that happens when you start a transaction while another transaction is already running, is adding an undo marker to the database. Any objects that are opened in any transaction regardless of nesting, will remain open until the outermost transaction is ended

 

These are some practices I try to adhere to, but I probably forgot a few. 

 

 

Message 3 of 4

That is a fantastic reply, thank you for your time. 

If I might ask one follow up regarding the end of your answer. I did not know and item would stay open until the outer most transaction is closed. If you needed an object at one point in the transaction, dispose it, then need it again at a later time what would you do? Because I've gotten "Object could not be retrieved because of the state of the object" (not exact wording) errors before?

Thank you again.

Message 4 of 4


@nshupeFMPE3 wrote:

That is a fantastic reply, thank you for your time. 

If I might ask one follow up regarding the end of your answer. I did not know and item would stay open until the outer most transaction is closed. If you needed an object at one point in the transaction, dispose it....


Dispose what?  The object or the transaction?

 

Regardless, a DBObject obtained from a transaction (nested or not) is only useable for the life of the outermost transaction (in the case of the type of Transaction returned by the TransactionManager's StartTransaction() method).  Once the outer-most transaction ends, any DBObjects obtained from it or any nested transactions are no longer usable.

 

In this context, the 'life' of a transaction starts when it is created, through the point where it's Commit(),  Abort()  or Dispose() method is called, whichever comes first.

 

The part about nesting only applies to TransactionManager transactions (the  type of Transaction returned by the TransactionManager's StartTransaction() method).

 

OpenCloseTransactions cannot be nested, so any DBObjects obtained from an OpenCloseTransaction are usable for the life of the OpenCloseTransaction which was used to open  the DBObject.

 

I said I probably forget a few things:

 

A DBObject's IsTransactionResident property is true if the DBObject was opened via a TransactionManager transaction, but will be false if the DBObject was opened using an OpenCloseTransaction.

 

Lastly, Transactions of any type should never be active when executing AutoCAD commands.

 

 

 

 

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

Post to forums  

Forma Design Contest


Autodesk Design & Make Report