Friday, August 29, 2008

Compensatable transactions

Up until now, when working with SQL Server, the most common transaction type I’ve used was the XA-style transaction. An XA transaction involves the XA protocol, which implements the two-phase commit (you’re probably familiar with this, most DBMS use it, but if you aren’t I suggest you go ahead and work on this issue, since it is essential when working with databases). The XA transactions, when using non-volatile resources, guarantees the ACID properties (Atomicity, Consistency, Isolation and Durability). This is all done at the DBMS level.

However, Windows Workflow Foundation “translates” this idea into an activity: the TransactionScope activity. What this means is that the activity knows how to use this kind of transactions without forcing the programmer to explicitly open a transaction. You just place activities inside the TransactionScope activity and that’s a XA-style transaction. You can even define the isolation level of the transaction for that activity (Serializable, Read Uncommitted, Repeatable Read and so on).

But WF also has another transaction style: The compensatable transactions. I wasn’t aware of this type of transactions up until now. The idea is basically the same as in XA-style transactions: if something goes wrong in one of the operations performed in the scope of the transaction, the data must go to a consistent state. But there’s a difference: When using XA-style transactions, if something fails, the transaction is “rolled back”. When using compensation, if something does fail, the transaction isn’t automatically “rolled back”. Instead, you must provide the actions to compensate the failure. To better explain, let me use the example given by Kenn Scribner: “If I give you five apples using a XA-style transaction and the transaction fails, time itself rewinds to the point I started to give you the apples. In a sense, history is rewritten such that the five apples were never given in the first place. But if I give you five apples in a compensated transaction and the transaction fails, to compensate (so that we maintain a determinate application state), you must return five apples to me.”

What this means is that the programmer is responsible for compensating, providing the actions to compensate the failed transaction. There is no “rollback”. Is this better than XA-style transactions? Well, it certainly gives you more control (and responsibility), but you must be very careful when writing compensation actions. The smallest mistake can leave a database in an inconsistent state.

I haven’t used this transaction style yet, but Kenn Scribner gives a hint on a few scenarios where it could be more useful then the XA-style transactions. I’m going to analyze these scenarios more deeply in order to see if it really makes sense.

Wednesday, August 20, 2008

WorkflowRuntime object

On chapter 1 of the book Windows Workflow Foundation Step by Step, the author states that “there can be only a single instance of the WorkflowRuntime per AppDomain”. When I was reading the book, I didn’t found this odd because it makes some sense. You only need one runtime.

In a recent project, however, I was presented with a scenario where I needed a different behaviour from the WorkflowRuntime when using multiple workflows. Simply put, I had 3 different workflows in the same AppDomain and I wanted the WorkflowRuntime to persist one of them and not the others. The only logical way to accomplish this behaviour was to implement myself a persistence service. Of course, I could also create another AppDomain and run another WorkflowRuntime in the new AppDomain but I don’t like this “workaround”.

Since I was short on time, after I googled a little I found that you can have more than one WorkflowRuntime per AppDomain. And this helped. Two WorklflowRuntime objects, one using the persistence service and the other one not using it. Yes, this leads to more resources consumption (the WorkflowRuntime isn’t a “cheap” object) but it was the quickest solution and I wasn’t concerned with performance.

Despite this “multiple WorkflowRuntime objects per AppDomain” feature, I still agree with the author of the book (Kenn Scribner) when he states that we should use a WorkflowRuntime Factory (Singleton and Factory patterns).

Here’s the errata page for the book: