document transaction status?

document transaction status?

Anonymous
Not applicable
4,881 Views
9 Replies
Message 1 of 10

document transaction status?

Anonymous
Not applicable

Does anyone know of a direct way to check whether a document has an in-progress transaction? I know how determine this indirectly by attempting to start a new transaction within a try-catch block and cheching for exceptions but I was looking for a more direct method. Something like bool Document.TansactionIsInProgress would be perfect if the dev team are listening. Smiley Happy I know about Transaction.GetStatus() but you need the original transaction object for this and I don't feel like passing it around to all of the many hundreds of helper methods in my library just in-case I might need it.

0 Likes
Accepted solutions (1)
4,882 Views
9 Replies
Replies (9)
Message 2 of 10

jeremytammik
Autodesk
Autodesk

Dear Scott,

 

have you tried subscribing to the ProgressChanged event?

 

you may also want to check out the Events/ProgressNotifier SDK sample.

 

ProgressChanged application event and ProgressChangedEventArgs

 

The application object now supports a ProgressChanged event and ProgressChangedEventsArgs object that returns progress bar data from time-consuming transactions.

  • ProgressChangedEventArgs
    • Caption – The name of the current transaction or subtransaction in progress
    • Stage – The type of progress event (Started, RangeChanged, PositionChanged, CaptionChanged, UserCancelled, Finished)
    • Position – The numerical index between zero and UpperRange showing the number of completed steps of the current transaction or subtransaction
    • UpperRange – The total number of steps in the current transaction or subtransaction
    • Cancel – Cancels the current transaction in progress, if possible.
    • Cancellable – indicates if the current transaction can be cancelled.

http://thebuildingcoder.typepad.com/blog/2013/03/whats-new-in-the-revit-2013-api.html

 

Please let us know whether it works and how you end up solving this.

 

Thank you!

 

Cheers,

 

Jeremy



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 3 of 10

Anonymous
Not applicable
I'll give it a go. Thanks Jeremy.
0 Likes
Message 4 of 10

arnostlobel
Alumni
Alumni
Accepted solution
Actually, Jeremy's answer is not entirely correct. The DocumentChanged event is to notify about transactions that has just ended. There is no indication of a transaction started, however.

The TransactionStatus property of a transaction is about the status of each and every one transaction object. Naturally, there can be many transaction instances in existence at the same time (owned by different applications or even by the same application), but only one of the object in each document would have its status equal to "Started" and that one object does not at all have to be yours. (I hope it make sense what I am saying.)

So, the only way to know whether a document is currently in a transaction or not is to test whether the document is "modifiable"; there is a method for that: Document.IsModifiable. If the value is True, the document can be currently modified, thus there must be an open transaction in it. However, keep in mind that a document can have an open transaction and yet not be modifiable. It happens when a document is in a read-only state (for whatever reason). There is a property for that too: Document.IsReadOnly. So, to sum it up, one can make changes in a document only if the document is modifiable and is not read-only.

That being said, it is for the best if each piece of code (method, subroutine, etc.) "knows" whether or not is supposed to be run when a document is modifiable or not. That should come with each method's contract. For example, external commands get invoked only when there is no transaction in the active document. Also events get raised only when there is no transaction in the document the event is about. On the other hand, dynamic updaters get invoked only when there is a transaction open in the document. Etc.

Arnošt
Arnošt Löbel
Message 5 of 10

Anonymous
Not applicable
Thanks Arnošt. The IsModifiable property seems more aligned to my needs. I think if combined with the readonly check it will do the job nicely.
0 Likes
Message 6 of 10

jeremytammik
Autodesk
Autodesk

Dear Arnošt,

 

Please note that I did not mention the DocumentChanged event, but the ProgressChanged event.

 

Can you please explain whether it can or cannot be useful in this situation?

 

I was especially thinking that the Caption property might provide what Scott is asking for – the 'name of the current transaction or subtransaction in progress'.

 

Scott, have you taken a look at this and the ProgressNotifier SDK sample at all?

 

Thank you!

 

Cheers,

 

Jeremy

 

 



Jeremy Tammik
Developer Technical Services
Autodesk Developer Network, ADN Open
The Building Coder

Message 7 of 10

arnostlobel
Alumni
Alumni

Oh, I have double vision. I noticed the progress event, but I thought I also saw document-changed event there. My bad; sorry about that, Jeremy.

 

Personally, I do not think I would suggest progress-changed events as a tool for watching when transactions start or when documents become modifiable, for several reasons:

  1. There is no connection between progress and transactions. There may be some actions in progress with no transactions whatsoever, like export; or there could be a progress with many transactions during the same action.
  2. I assume the original question was asked to find a mean for modifiability of a document and I assumed the intend was to actually modify a document (if it happens to be modifiable). I cannot recommend modifying a document during progress-changed event, because - well, it is a progress of action action and the originator of that other action probably does not expect other application making modification. In fact, I believe the document should be put in a temporary read-only state during each progress-changed event. (I do not if it is, but it should be.)

Does that make sense?

 

I can also repeat what I stated before - ideally, an application and its routines (methods) should know at most of the time whether there are invoked during a transaction or not. There should be a strict contract between callers of a method and the method self; for example: a caller should know that a method is to modify a document and is to expect the document be modifiable already. If that is the contract then it is the responsibility of the caller make sure there is a transaction open before the method is invoked. I understand life is not always this straightforward and simple, but in most common cases a transaction contract is not difficult to maintain.

Arnošt Löbel
Message 8 of 10

Anonymous
Not applicable
My use-case for this is a multi-purpose get/create method that looks for a specific model line type and either returns it if found or creates a new one and returns that. I want the method to be smart enough to switch between using a SubTransaction when a Transaction is already in progress and creating its own Transaction when needed.
0 Likes
Message 9 of 10

arnostlobel
Alumni
Alumni

Scott,

 

of course, you do not have to take my advice, but I generally advise against methods like the one you described. What I mean by it is that if I see it in a code I am code-reviewing, will ask the programmer to refactor it. In my opinion which is based on years of experience (just a fact, I do not mean to brag), simple code wins over super smart one in the long run. I like methods to be simple and straightforward and doing one thing well and one thing only. If a method is to get a element, then it should just find and return that element, and not try creating one if it cannot find it. And vice versa - if an element is to be created, then it should not exist yet, and the method that creates that element should throw if the elements is found. Thus I can repeat one more time - methods should be structured around basic and as simple as possible contracts - if a method is to modify a document, it should then either be expected to have its own transaction, or it should expect the caller have a transaction open for it. In either of the two cases, the contract needs to be know to both the caller and the callee. In my opinion and experience this is the best way to create a clean and maintainable code.

Arnošt Löbel
Message 10 of 10

Anonymous
Not applicable
Yeah its probably a bit of laziness on my part. This project is starting to really drag on (I've been 90% complete for 8 months now as I have been recovering from major brain surgery ) and the shortcommings of my initial design are becomming magnified as I try to cobble the final touches into wherever they'll fit (I still haven't done any significant optimisation either).

Thanks for the advice. I'm quite the self-taught solo cowboy coder so I appreciate practical advice from a more disciplined practioner.