COM+ and System.Transactions living happily ever after

Recently I had an issue where I had to use a COM+ transactional component from a WCF service. I was porting some old functionality from another COM+ component to a WCF service, when I stumbled across this issue.

The new and shiny way to replace ServicedComponents, is of course to use the System.Transactions namespace. So, in good faith, I created a new using TransactionScope section, where I put the calls to two different, transactional COM+ components inside, and Completed the scope right before the end using statement, as is considered good practice (http://msdn.microsoft.com/en-us/library/system.transactions.transactionscope.complete.aspx).

However, we had some problems with a backend system used by one of the components, so the call to it kept failing all the time. However irritating a failing system might be, this time I was actually lucky the system was failing. Because then I got to test my transactional rollbacks. And, to my surprise, the rollbacks weren’t executed in component 2 when component 1 failed.

Then I started googling (as always – how could I ever do anything but Hello World’s without google…), and came across this article: Interoperability with Enterprise Services and COM+ Transactions . It explains that when you need to interoperate with COM+ transactions from a lightweight System.Transactions transaction, you need to specify the EnterpriseServicesInteropOption value to the TransactionScope contructor. The examples in the article above were all trying to get a pure .NET TransactionScope component to take part in an existing EnterpriseServices (COM+) transaction. After a bit of trial and error, I found that to actually initiate a COM+ transaction from pure .NET code, you need to specify the EnterpriseServicesInteropOption.Full option. This makes .NET always create a COM+ compatible transaction, and any COM+ component called within that scope will take part in the transaction created.

All things worked, and I was happy.

When writing this blog post, I came across the following articles, which do actually explain the scenario I was trying to get to work:

Here is an example from the link above:

 public void UpdateCustomerNameOperation(int customerID, string newCustomerName)
   {
   // Create a transaction scope with full ES interop
      using (TransactionScope ts = new TransactionScope(
                     TransactionScopeOption.Required,
                     new TransactionOptions(),
                     EnterpriseServicesInteropOption.Full))
      {
         // Create an Enterprise Services component
         // Call UpdateCustomer method on an Enterprise Services 
         // component 

         // Call UpdateOtherCustomerData method on an Enterprise 
         // Services component 
         ts.Complete();
      }
      // Do UpdateAdditionalData on an non-Enterprise Services
      // component
   }

So, COM+ EnterpriseServices transactions and System.Transactions do play well together, you just need to set the EnterpriseServicesInteropOption correctly when you instantiate your TransactionScope TransactionScope Constructor (Transaction, TimeSpan, EnterpriseServicesInteropOption).

Advertisements
This entry was posted in .NET, C#, COM+. Bookmark the permalink.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s