Don’t Use Workflow Bookmarks in Transaction Scopes

Wednesday, September 7, 2011

It’s been a while since I posted about a workflow-related bug, and it’s not because of my mad WF skillz – it had more to do with Manu’s expertise in the big WF project I’m involved in. The following bug slipped through the cracks and is worth sharing. One of our custom activities sends a query to the user and waits for a response. This can take days – a human operator is not always available to answer the question, and some questions may require escalation. In one of our recent workflows, two queries had to be sent...
no comments

Debugging Distributed Transactions: Additional Examples

Thursday, July 29, 2010

In this final installment we’ll take a look at some additional examples of problems caused by distributed transactions. The following execution history results in a deadlock. What would you suggest to address it? Time Transaction 1 (Inventory Service) Transaction 2 (Shipping Service) 0 Select all orders by...
no comments

Debugging Distributed Transactions: Transactional Deadlocks, Part 2

Thursday, July 22, 2010

It’s time to add WCF services to the mix and see how their presence adds to the complexity of the otherwise non-trivial transactional deadlocks. Consider the following transaction: Client: Begin transaction Client: Select all orders by customer A Client: Call a WCF service and pass to it the list of orders Service: Update the shipping date of all selected orders Client: Commit If both parties share the same distributed transaction, it completes successfully. However, if the...
no comments

Debugging Distributed Transactions: Transactional Deadlocks, Part 1

Monday, July 19, 2010

The most commonly encountered problem with distributed transactions is that of transactional deadlocks. Transactions guarantee isolation, which is usually effected through locks. This is the case with SQL Server (as well as other relational databases) transactions. Transaction isolation levels provide additional granularity as to when and whether the locks are released prior to the completion of the transaction. Database Locks Simply put, the database issues shared (read) and exclusive (write) locks on data touched by the transaction. For most practical purposes, a SELECT statement effects a shared lock on all the rows returned by the statement, while...
no comments

Debugging Distributed Transactions: Fault Handling

Saturday, July 17, 2010

How is a WCF service call under a distributed transaction different from a regular WCF service call? The primary difference is the transactional abort semantics in case of failure. If the WCF service operation fails when there is no ambient transaction, the failure can be contained—the service caller may decide to ignore the error and proceed. However, if the WCF service operation fails within a distributed transaction, the transaction’s abort flag is set (by default), so that the caller cannot proceed with the transaction. In other words, if you handle a fault from a transactional WCF service and...
no comments

Debugging Distributed Transactions: Configuring WCF Transaction Flow

Wednesday, July 14, 2010

This is the first in a short series of posts in which we’ll debug problems that arise from the use of distributed transactions in WCF. Particularly, we will look into deadlocks, timeouts, and miscellaneous transaction-related issues. To begin with, here’s a brief recap of what has to be done to flow a transaction across WCF service calls: The WCF operation must be decorated with the attribute and the TransactionFlowOption enum. You can either disallow, allow, or mandate transaction flow to the service operation—violations of the contract result in a ProtocolException on the caller’s...
no comments

Transactional Workflows: Suspend-Enqueue-Unload-Resume Done Correctly on Second-Phase Commit

Friday, May 21, 2010

More than two years ago I visited the subject of transactionally delivering a message to a workflow, making sure that the transaction did not commit until the message has been delivered and the workflow persisted under the same transaction. This subject has also been covered fairly well in this MSDN Forums thread. As a quick reminder, if you want to transactionally deliver a message to a workflow, you need to follow these steps: Suspend the workflow instance Enqueue the message to the workflow’s queue Unload the...
no comments

Transaction Flows Across Reentrant AppDomain Calls

A few of weeks ago I blogged about flowing a transaction across AppDomain boundaries. Apparently, there’s a little gotcha that you need to be aware of: Even if you don’t flow the transaction to the other AppDomain, and the thread in the other AppDomain executes a method that calls back into the original AppDomain, the transaction will flow across the reentrant call. In other words, if you have two objects, A and B, where A lives in one AppDomain and B lives in another AppDomain, then the following can happen: A calls a method of B within a...
no comments

Propagating a Transaction Across AppDomains

Friday, April 30, 2010

Earlier this week I had to propagate a System.Transactions transaction across .NET AppDomains. If you use a TransactionScope and rely on the ambient transaction propagation, you’ll find that the transaction does not cross the AppDomain boundary. This actually makes sense from an isolation perspective—transactions represent an isolation boundary and have their own failure semantics, while AppDomains represent another isolation boundary and have other failure semantics. There are several ways to propagate a transaction across AppDomains, but bear in mind that regardless of the method you choose, the transaction will be promoted to a distributed transaction when it flows...