Tuesday, February 3, 2009

Stay away from pseudo-transactions!

I tried to stay clear of commenting on this article, but while participating in tonight's WS-RA meeting I let my defenses down! In short, the article can be summarized by: "How to use non-transactional resources in a transaction when you can't be bothered to do it right in the first place." Or "How I learned to break transactional semantics and put my data consistency on the line."

I'm fairly sure the authors are trying to help their audience, but they really aren't. They ignore critical problems with their proposal, either deliberately or because they simply haven't given the problem space enough thought. What they are trying to do is emulate the last-resource commit optimization within the application, but whereas a transaction manager will do this and provide support for crash failures, the article ignores that completely. There is no reference to failure recovery at all.

The article also appears to assume that because a datasource is managed by an XAResource it will always honor the business logic agreement when the transaction commits, e.g., if the table update succeeded through the session instance then prepare/commit will work later. I hate to break it to the authors, but that isn't always the case. This works in a transaction manager because we manage the resource ordering and durability very carefully to cope with failures, i.e., there are good reasons we don't require the application programmer to do this!

Oh and the way in which multiple non-transactional resources are managed in the transaction just scares the %$&* out of me! Look, these are resources that do their work when told to and you can't undo that (if you could, then wrap the &%*& things in an XAResource!) So if you crash part way through the normal flow of execution, or part way through the "rollback", what is the state of the application? How do you find out what happened to whom and when? Where's the log?! (I would hate to be a systems administrator in this situation when the sh*t hits the fan!)

The authors say that "Although this is not as robust and comprehensive as a truly transactional interface, it can provide excellent coverage at a fraction of the development cost of a JTA compliant interface." Unfortunately it does not. That's a bit like saying a car with worn brakes is roadworthy in all situations, when it clearly isn't! Ask yourself this: what happens to my data in the cases that aren't covered by this approach and can I really afford to lose it or spend the new hours/days/weeks repairing it manually? If the answer is yes, then you probably don't want to use transactions at all. If the answer is no, then stay away from this approach and go with a transaction system and transactional resources.

In conclusion: use transactions correctly and if you can't make your data items transactional then try using compensating transactions. At least you get logging and recovery!

No comments: