Andres Aguiar's Weblog

Just My Code

September 2004 - Posts

Compensating transactions with DataSets

When building SO applications you usually need to write code to compensate failing transactions.

When you call two services that can't (or shouldn't) be called in the same transactional context, and the second fails you need to 'rollback' the first one by executing code that undoes the operation.

Suppose you have a Business Logic Layer method that receives an ADO.NET DataSet, and the method does the 'right thing' when you perform any insert/update/deleted operation in the DataSet. In this case, it's possible to automatically compensate the transaction by reversing the operations in the DataSet.

The DataSet knows all the operations you performed on data and all the previous values. You can build a DataSet that perform the opposite operations. For example, if you added a row in the DataSet, then you can have that row as Deleted in the new one. If you changed it, you can have it changed but the reverse way (the old value now is the new one and viceversa). If you deleted a row, you can have it added in the DataSet.

You could write:


CustomerDataSet ds ;

// load it somehow, retrieving it from a webservice or whatever, and change it

CustomerDataSet reverseDs = (CustomerDataSet) DataSetUtil.ReverseDataSet(ds);

customerManager.Update(ds);

...

// if other service fails, compensate the transaction

customerManager.Update(reverseDs);

It seems to work pretty well, but there are a couple of gotchas:

  • As the .Update() method calls .AcceptChanges(), you need to have the reversed dataset before calling Update()
  •  If the Update() method refreshes values in the DataSet (for example, it loads an identity field), then you'll need to set that value in the reversed DataSet after calling .Update(ds) and before calling .Update(reverseDS). It will end up as something like:

CustomerDataSet ds ;

// load it somehow, retrieving it from a webservice or whatever, and change it

CustomerDataSet dsCopy = (CustomerDataSet) ds.Copy();

customerManager.Update(ds);

dsCopy.Customers[0].CustomerId = ds.Customers[0].CustomerId;

customerManager.Update(DataSetUtil.ReverseDataSet(dsCopy));

 

It should also be possible to make the Update() method returns the reverse dataset, relieving the client-side developer from knowing which field is updated by the customerManager. That's probably a good solution if you know the operation will need to be included in a compensating transaction.

This solution will probably don't work for all the scenarios, but if it does, it saves a lot of error-prone coding.

You can find the code for the ReverseDataSet method here. It has zero test in production environments ;).

Layered Architecture vs Living Domain Model

Ben Hogan has a an interesting post about the compatiblity between having a rich domain model and a layered architecture.

I agree with Jon Tirsen on this. It's not practical.

I also agree that a web application does not need a layered architecture. The problem is that if you want to reuse your domain model in a different scenario (like a rich client app) then you'll need the layered architecture, and your domain model will be pretty much useless, or it will require a significant refactoring.

 

iTunes and Windows Media Player

After CNet and Chris Anderson now is my turn to compare WMP 10 and iTunes ;)

Last Friday I downloaded WMP 10.0 and I liked it. I never looked at iTunes because I did not find a reason to do it.

Today a coworker showed me the coolest iTunes feature, which IMHO is that you can share music with the people in the same network. I installed it, and I can stop using it. Is like I'm listening to music just as an excuse to use iTunes ;). You just tell iTunes you want to share your music and everyone else sees it as part of his iTunes experience.

Of course, this made me an iTunes evangelist, as now I want everyone in the office to use it. It converts WMAs to AACs when you try to add WMAs, so unless you have a lot of WMAs it's not a big issue.

On the other hand, there are a couple of features that at first I thought it had but it has not. One is the ability to search for music globally. You can search only in one user's list at a time. The other is the ability to have a common playlist where each one adds some songs and everyone listens to them.

For searching globally, there is a Java program called ourTunes that does it, and it also allows you to download the audio files to your computer (iTunes just lets you listen to them). The fact that you can write code to talk to the iTunes servers is also cool and opens a lot of possiblities for third party tools.

As everyone in the office was playing with iTunes I also noticed that my Thinkpad T42 speakers suck compared to my coworkers Toshiba's.

 

Fun with ASP.NET 2.0 build system

Fritz Onion is having fun with the ASP.NET 2.0 build system.

I'm not sure it's a good idea for production use. My Business Logic Layer, which will be the one to use the DAL, won't be in a ASP.NET project ;)

Anyway, it's fun

 

WinFS, MBF and 'Integrated Innovation'

I wonder how responsible MBF is on WinFS delay. I have the feeling that quite a lot. If WinFS scope was to be 'just' a file system over a relational database where you can find things quickly, I think it would still be in Longhorn.

The MBF team has a lot of power. They can influence the way WinFS is designed to it fits their needs. They are not using WinFS as a component, they are integrating with it at the source code level. This is very different from the way these kinds of applications were built previously. When ISVs built applications on Microsoft platforms, they used the platform as a component. They had to learn the limitations and find ways to make things work. When the Windows version changed, the applications usually continued working. That's the way Great Plains and a lot of other ERP like applications were built.

This means WinFS will be tightly coupled with MBF. Is this a good or a bad thing? We can't be sure. Platforms components usually need to be tightly coupled. The question is if MBF should be part of the platform.

Rick Chapman, in 'In Search of Stupidity' says that Microsoft survived because it was the only company that never made a fatal, stupid mistake.

Would the whole MBF/MBS thing be the fatal one?

PS: Of course, perhaps MBF is not related at all with WinFS delay, but anyway this post was fun to write ;).

More Posts