Modify the model inside of a transaction

So I took over a project from someone else who apparently had not read the documentation. ;) All of the operations that add and remove nodes and links are now wrapped inside transactions. However, I’m wondering what’s the right way to modify properties on those node and link model objects. For example, if I extend GraphLinksModelNodeData to add a property “Foo” which I then bind in my node template, do I need to modify the Foo property inside of a transaction? Or is the fact that the node model was added to the GraphLinksModel inside of a transaction sufficient?

If that data is already in the model when you modify it, yes, the change ought to be within a transaction. It might work without, but you’d be depending on other things happening to mask the deficiency.

Although it might work to start and commit a transaction in the property setter, it’s unnatural.
It makes a lot more sense to wrap any command-implementing or other event-handling code in a transaction, if that code might modify the model or its data.

Some follow up questions:

  1. What happens in the case of a nest asynchronous transaction? That is, I start a transaction which starts a nested transaction. The nested transaction hits a web service so it’s logic is delayed until the web service responds. However, the call chain returns in the meantime and the parent transaction is committed. The nested transaction does not call CommitTransaction until the web service responds or times out.

  2. What is the impact of not modifying the model inside of a transaction? Essentially, why does it matter that I modify my model inside of a transaction?

GoXam only operates in the presentation layer, so there’s no concept of dealing with asynchronous external operations. I don’t think nested transactions should be involved with such external things. But you could do so when a top-level transaction has committed. It’s commonplace to check for the ModelChange.CommittedTransaction change to be notified when a top-level transaction has happened.

If you make model changes outside of a transaction, a rollback might do the wrong things. Undo and redo may do the wrong set of things too.

Thank you, that information was helpful. I do have one more question: our application is designed around shared data transfer objects (sDTO). A component retrieves an sDTO which is then available to all components. Any component can act upon and modify an sDTO (change it’s name and address, for example). An sDTO also provides a binding surface so it can be directly used from XAML without further exploding the data.

If I have an sDTO as part of a node model object, I can’t wrap a change to its Name property inside of Start/CommitTransaction blocks. Some other component updates the data and my GoXam diagram updates via data binding. It seems like this design is not compatible with GoXam. What would you advise? (I wouldn’t expect to undo any of these external changes, BTW.)

So those properties use the INotifyPropertyChanged protocol? And all such changes occur in the UI thread as is normal for view models? And you’re not using an UndoManager?

Things might just work the way you want, but it might depend on what kinds of properties that you have data-bound. I don’t know enough to hazard a guess.

That’s mostly correct: the properties use INotifyPropertyChanged, all changes occur in the UI thread, but I am using an UndoManager. The only purpose of the UndoManager was to work around an issue with the linking tool, but I think you’ve answered that in another thread and I can probably remove it.

We provide several kinds of properties: basic strings, numbers, and dates plus aggregate formatting objects. Formatting objects provide standard look and feel properties such as color, line style, text formatting (bold, italic, underline), etc.

Well, if they are just non-GoXam FrameworkElement properties that are data-bound to your sDTO objects, and you are not using an UndoManager, that might work OK without transactions.