Thanks for the reply!
Our main concern, and the reason we want to know if events run synchronously, is whether we need to be concerned about race conditions and thread safety when using AlfrescoTransactionSupport.getResource() and AlfrescoTransactionSupport.bindResource().
Our current plan is to create a collection to track all of the nodes that were edited in the transaction, much the same way that Angel used an array to collected related nodes. Then, when the transaction is done, we will use that collection to report out, to an external queue, the final state of each node edited in that transaction. We are going down this path because we can never know in the event handler whether this is the final event for a given node or not, and we don't want the overhead of doing external IO on every event.
The concern is that if these events run asynchronously, then there is no garantee that two separate events won't call getResource at about the same time and get a null value, and then call bindResource with a new collection so that the last one in wins and the first one is just lost.
I can see how your transactionCounter method will let you find the last event fired without worring about the concurrency issues I just described, but I don't think it will handle the situation where there are multiple nodes edited within a ransaction... at least as far as I understand it now.