Last month, I wrote a post about compensatable transactions, but left a question in the air: how really useful can this kind of transactions be and where to apply it?
Well, when reading Kenn Scribner’s book about WF, I didn’t catch the “big picture”. XA-style transactions seemed enough. But after reading a couple of articles from the WF Team at the MSDN magazine, I understood what Kenn Scribner was talking about in the book.
Here’s an example from me that better describes his thoughts (although not far from his example). Keep in mind that depending on the isolation level you choose for a XA-style transaction data may became locked throughout the entire transaction scope.
Imagine that you have to develop an intranet for a company with several departments, all of them with the ability to place orders for material specific to their business area. Of course, all the orders must be approved by the accounts man before sent to the suppliers and paid. Would you use a XA-style transaction throughout the process? What if the accounts man takes hours (or days!) to approve the order, should the data be locked for that period? Further more, if an exception happens, should we roll back and some orders where miraculously never placed or never shipped to the supplier? What happens to transactional tasks in the context of a larger process where you can’t lock data for too long and must be able to roll back past commits?
This is much the example he gave. In a long running process, you might have to split one action that you would desire to be atomic, breaking one of the ACID properties: atomicity. The idea was that from the time the employee places the order until the order actually gets to the supplier and paid, it’s all or nothing.
Compensatable transactions allow this scenario. Quoting Dino Esposito at MSDN magazine, “compensation is any logic you run at some point to undo, mitigate, or compensate for the effects of previous operations. The point is that the compensatable transaction might contain child ACID transactions that, once committed, can’t be rolled back any longer. However, in case of a further failure, their effects must be compensated for in some way. Compensation is like rollback except that the developer is called to write any code used to compensate for the work done.”
Dino Esposito actually goes on and answers my question: why bother with compensation? “When different companies and services are involved, defining the process in terms of the ACID semantics is often challenging. For it to be isolated and durable, you have to keep all resources of different companies locked for the duration of the task. This is frequently unreasonable, especially if the task is long.”
After all this talk, let’s resume: although the idea behind both the transaction types I’ve mentioned is the same, they’re actually quite different. Obviously, you want your XA-style transactions to be as short as possible for a variety of reasons (most important, data might get locked) while in a compensatable scenario this isn’t true.
Although I haven’t used it yet (nor I’m expecting to), it’s a great thing that WF incorporates this concept.